Error executing template "Designs/Rapido/_parsed/ContentPage.parsed.cshtml"
System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) ---> System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()
   at Dynamicweb.Data.DatabaseConnectionProvider.CreateConnection(Boolean open)
   at Dynamicweb.Data.Database.CreateConnection()
   at Dynamicweb.Data.Database.CreateDataReader(CommandBuilder commandBuilder, IDbConnection connection, IDbTransaction transaction, Int32 commandTimeout)
   at Dynamicweb.Ecommerce.Products.ProductRepository.GetProductById(String productId, String productVariantId, String productLanguageId)
   at Dynamicweb.Ecommerce.Products.ProductService.FetchMissingProductsInternal(IProductRepository repo, IEnumerable`1 keys)
   at Dynamicweb.Caching.ServiceCache`2.GetCache(IEnumerable`1 keys)
   at Dynamicweb.Caching.ServiceCache`2.GetCache(TKey key)
   at Dynamicweb.Ecommerce.Products.ProductService.GetProductById(String productId, String productVariantId, String productLanguageId, User user, Boolean showUntranslated)
   at Dynamicweb.Ecommerce.Products.ProductService.GetProductById(String productId, String productVariantId, String productLanguageId, Boolean useAssortments)
   at Dynamicweb.Ecommerce.Products.ProductService.GetProductById(String productId, String productVariantId, String productLanguageId)
   at CompiledRazorTemplates.Dynamic.RazorEngine_4b7a7dab9ac64fecbe50b47a7275917e.GetProductFieldValue(String productField) in D:\dynamicweb.net\Solutions\Philipson Wine\Files\Templates\Designs\Rapido\_parsed\ContentPage.parsed.cshtml:line 13224
   at CompiledRazorTemplates.Dynamic.RazorEngine_4b7a7dab9ac64fecbe50b47a7275917e.Execute() in D:\dynamicweb.net\Solutions\Philipson Wine\Files\Templates\Designs\Rapido\_parsed\ContentPage.parsed.cshtml:line 13314
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
ClientConnectionId:00000000-0000-0000-0000-000000000000
Error Number:2,State:0,Class:20

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 2 3 @using System.Web; 4 @using Dynamicweb 5 @using Dynamicweb.Frontend 6 @using Dynamicweb.Frontend.Devices 7 @using Dynamicweb.Extensibility 8 @using Dynamicweb.Content 9 @using Dynamicweb.Security 10 @using Dynamicweb.Core 11 @using System 12 @using System.Web 13 @using System.IO 14 @using System.Text.RegularExpressions; 15 @using Dynamicweb.Rapido.Blocks 16 @using System.Net 17 @using Dynamicweb.Logging 18 @using Dynamicweb.Environment; 19 20 21 @functions { 22 BlocksPage masterPage = BlocksPage.GetBlockPage("Master"); 23 24 string getFontFamily(params string[] items) 25 { 26 var itemParent = Pageview.AreaSettings; 27 foreach (var item in items) 28 { 29 itemParent = itemParent.GetItem(item); 30 if (itemParent == null) 31 { 32 return null; 33 } 34 } 35 36 var googleFont = itemParent.GetGoogleFont("FontFamily"); 37 if (googleFont == null) 38 { 39 return null; 40 } 41 return googleFont.Family.Replace(" ", "+"); 42 } 43 44 } 45 46 @{ 47 Block root = new Block 48 { 49 Id = "Root", 50 SortId = 10, 51 BlocksList = new List<Block> 52 { 53 new Block { 54 Id = "Head", 55 SortId = 10, 56 SkipRenderBlocksList = true, 57 Template = RenderMasterHead(), 58 BlocksList = new List<Block> 59 { 60 new Block { 61 Id = "HeadMetadata", 62 SortId = 10, 63 Template = CustomRenderMasterMetadata(), 64 }, 65 new Block { 66 Id = "HeadCss", 67 SortId = 20, 68 Template = RenderMasterCss(), 69 }, 70 new Block { 71 Id = "HeadManifest", 72 SortId = 30, 73 Template = RenderMasterManifest(), 74 } 75 } 76 }, 77 new Block { 78 Id = "Body", 79 SortId = 20, 80 SkipRenderBlocksList = true, 81 Template = RenderMasterBody(), 82 BlocksList = new List<Block> 83 { 84 new Block() 85 { 86 Id = "Master", 87 SortId = 10, 88 BlocksList = new List<Block> { 89 new Block { 90 Id = "MasterTopSnippets", 91 SortId = 10 92 }, 93 new Block { 94 Id = "MasterMain", 95 SortId = 20, 96 Template = RenderMain(), 97 SkipRenderBlocksList = true, 98 BlocksList = new List<Block> { 99 new Block { 100 Id = "MasterHeader", 101 SortId = 10, 102 Template = RenderMasterHeader(), 103 SkipRenderBlocksList = true 104 }, 105 new Block { 106 Id = "MasterPageContent", 107 SortId = 20, 108 Template = RenderPageContent() 109 }, 110 new Block { 111 Id = "MasterPageOverlay", 112 SortId = 30, 113 Template = RenderOverlay() 114 } 115 } 116 }, 117 new Block { 118 Id = "MasterFooter", 119 SortId = 30 120 }, 121 new Block { 122 Id = "MasterReferences", 123 SortId = 40 124 }, 125 new Block { 126 Id = "MasterBottomSnippets", 127 SortId = 50 128 } 129 } 130 } 131 } 132 } 133 } 134 }; 135 136 masterPage.Add(root); 137 } 138 139 @{ 140 bool isHeaderHidden = Model.PropertyItem.GetBoolean("HideHeader"); 141 bool isFooterHidden = Model.PropertyItem.GetBoolean("HideFooter"); 142 string fileVersion = Converter.ToString(System.Web.HttpContext.Current.Cache["FileVersion"]); 143 if (string.IsNullOrEmpty(fileVersion)) 144 { 145 try 146 { 147 var assembly = System.Reflection.Assembly.Load("Application"); 148 if (assembly != null) 149 { 150 fileVersion = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion; 151 System.Web.HttpContext.Current.Cache["FileVersion"] = fileVersion; 152 } 153 } 154 catch (Exception ex) 155 { 156 LogManager.Current.GetLogger("Smartpage/Assemblies").Error("Error while loading Application assembly: ", ex); 157 } 158 } 159 } 160 161 @* Include the required Grid builder (Contains the methods @RenderBlockList and @RenderBlock) *@ 162 @using System.Text.RegularExpressions 163 @using System.Collections.Generic 164 @using System.Reflection 165 @using System.Web 166 @using System.Web.UI.HtmlControls 167 @using Dynamicweb.Rapido.Blocks.Components 168 @using Dynamicweb.Rapido.Blocks.Components.Articles 169 @using Dynamicweb.Rapido.Blocks.Components.Documentation 170 @using Dynamicweb.Rapido.Blocks 171 172 173 @*--- START: Base block renderers ---*@ 174 175 @helper RenderBlockList(List<Block> blocks) 176 { 177 bool debug = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("debug")) ? Convert.ToBoolean(HttpContext.Current.Request.QueryString.Get("debug")) : false; 178 blocks = blocks.OrderBy(item => item.SortId).ToList(); 179 180 foreach (Block item in blocks) 181 { 182 if (debug) 183 { 184 <!-- Block START: @item.Id --> 185 } 186 187 if (item.Design == null) 188 { 189 @RenderBlock(item) 190 } 191 else if (item.Design.RenderType == RenderType.None) 192 { 193 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : ""; 194 195 <div class="@cssClass dw-mod"> 196 @RenderBlock(item) 197 </div> 198 } 199 else if (item.Design.RenderType != RenderType.Hide) 200 { 201 string cssClass = item.Design.CssClass != null ? item.Design.CssClass : ""; 202 203 if (!item.SkipRenderBlocksList) 204 { 205 if (item.Design.RenderType == RenderType.Row) 206 { 207 <div class="grid grid--align-content-start @cssClass dw-mod" id="Block__@item.Id"> 208 @RenderBlock(item) 209 </div> 210 } 211 212 if (item.Design.RenderType == RenderType.Column) 213 { 214 string hidePadding = item.Design.HidePadding ? "u-no-padding" : ""; 215 string size = item.Design.Size ?? "12"; 216 size = Regex.IsMatch(size, @"\d") ? "md-" + item.Design.Size : item.Design.Size; 217 218 // Used to remove sticky--facet class from Navigation if there are no products 219 if (item.Id == "Navigation") 220 { 221 222 <text> 223 {{#if totalProductsCount}} 224 <div class="grid__col-lg-@item.Design.Size grid__col-md-@item.Design.Size grid__col-sm-12 grid__col-xs-12 @hidePadding @cssClass dw-mod" id="Block__@item.Id"> 225 @RenderBlock(item) 226 </div> 227 {{else}} 228 <div class="grid__col-lg-@item.Design.Size grid__col-md-@item.Design.Size grid__col-sm-12 grid__col-xs-12 @hidePadding dw-mod" id="Block__@item.Id" style="top: 75px; position: sticky; align-self: baseline; overflow-y: auto;"> 229 @RenderBlock(item) 230 </div> 231 {{/if}} 232 233 </text> 234 } 235 else 236 { 237 <div class="grid__col-lg-@item.Design.Size grid__col-md-@item.Design.Size grid__col-sm-12 grid__col-xs-12 @hidePadding @cssClass dw-mod" id="Block__@item.Id"> 238 @RenderBlock(item) 239 </div> 240 } 241 } 242 243 if (item.Design.RenderType == RenderType.Table) 244 { 245 <table class="table @cssClass dw-mod" id="Block__@item.Id"> 246 @RenderBlock(item) 247 </table> 248 } 249 250 if (item.Design.RenderType == RenderType.TableRow) 251 { 252 <tr class="@cssClass dw-mod" id="Block__@item.Id"> 253 @RenderBlock(item) 254 </tr> 255 } 256 257 if (item.Design.RenderType == RenderType.TableColumn) 258 { 259 <td class="@cssClass dw-mod" id="Block__@item.Id"> 260 @RenderBlock(item) 261 </td> 262 } 263 264 if (item.Design.RenderType == RenderType.CardHeader) 265 { 266 <div class="card-header @cssClass dw-mod"> 267 @RenderBlock(item) 268 </div> 269 } 270 271 if (item.Design.RenderType == RenderType.CardBody) 272 { 273 <div class="card @cssClass dw-mod"> 274 @RenderBlock(item) 275 </div> 276 } 277 278 if (item.Design.RenderType == RenderType.CardFooter) 279 { 280 <div class="card-footer @cssClass dw-mod"> 281 @RenderBlock(item) 282 </div> 283 } 284 } 285 else 286 { 287 @RenderBlock(item) 288 } 289 } 290 291 if (debug) 292 { 293 <!-- Block END: @item.Id --> 294 } 295 } 296 } 297 298 @helper RenderBlock(Block item) 299 { 300 bool debug = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("debug")) ? Convert.ToBoolean(HttpContext.Current.Request.QueryString.Get("debug")) : false; 301 302 if (item.Template != null) 303 { 304 @BlocksPage.RenderTemplate(item.Template) 305 } 306 307 if (item.Component != null) 308 { 309 string customSufix = "Custom"; 310 string methodName = item.Component.HelperName; 311 312 ComponentBase[] methodParameters = new ComponentBase[1]; 313 methodParameters[0] = item.Component; 314 Type methodType = this.GetType(); 315 316 MethodInfo customMethod = methodType.GetMethod(methodName + customSufix); 317 MethodInfo generalMethod = methodType.GetMethod(methodName); 318 319 try 320 { 321 if (debug) 322 { 323 <!-- Component: @methodName.Replace("Render", "") --> 324 } 325 @customMethod.Invoke(this, methodParameters).ToString(); 326 } 327 catch 328 { 329 try 330 { 331 @generalMethod.Invoke(this, methodParameters).ToString(); 332 } 333 catch (Exception ex) 334 { 335 throw new Exception(item.Component.GetType().Name + " method '" + methodName + "' could not be invoked", ex); 336 } 337 } 338 } 339 340 if (item.BlocksList.Count > 0 && !item.SkipRenderBlocksList) 341 { 342 @RenderBlockList(item.BlocksList) 343 } 344 } 345 346 @*--- END: Base block renderers ---*@ 347 348 349 @* Include the components *@ 350 @using Dynamicweb.Rapido.Blocks.Components 351 @using Dynamicweb.Rapido.Blocks.Components.General 352 @using Dynamicweb.Rapido.Blocks 353 @using System.IO 354 355 @* Required *@ 356 @using Dynamicweb.Rapido.Blocks.Components 357 @using Dynamicweb.Rapido.Blocks.Components.General 358 @using Dynamicweb.Rapido.Blocks 359 360 361 @helper Render(ComponentBase component) 362 { 363 if (component != null) 364 { 365 @component.Render(this) 366 } 367 } 368 369 @* Components *@ 370 @using System.Reflection 371 @using Dynamicweb.Rapido.Blocks.Components.General 372 373 374 @* Component *@ 375 376 @helper RenderIcon(Icon settings) 377 { 378 if (settings != null) 379 { 380 string color = settings.Color != null ? "style=\"color: " + settings.Color + "\"" : ""; 381 382 if (settings.Name != null) 383 { 384 if (string.IsNullOrEmpty(settings.Label)) 385 { 386 <i class="@settings.Prefix @settings.Name @settings.CssClass" @color></i> 387 } 388 else 389 { 390 if (settings.LabelPosition == IconLabelPosition.Before) 391 { 392 <span>@settings.Label <i class="@settings.Prefix @settings.Name @settings.CssClass" @color></i></span> 393 } 394 else 395 { 396 <span><i class="@settings.Prefix @settings.Name u-margin-right--lg @settings.CssClass u-w20px" @color></i>@settings.Label</span> 397 } 398 } 399 } 400 else if (!string.IsNullOrEmpty(settings.Label)) 401 { 402 @settings.Label 403 } 404 } 405 } 406 @using System.Reflection 407 @using Dynamicweb.Rapido.Blocks.Components.General 408 @using Dynamicweb.Rapido.Blocks.Components 409 @using Dynamicweb.Core 410 411 @* Component *@ 412 413 @helper RenderButton(Button settings) 414 { 415 if (settings != null && (!string.IsNullOrEmpty(settings.Title) || settings.Icon != null)) 416 { 417 Dictionary<string, string> attributes = new Dictionary<string, string>(); 418 List<string> classList = settings.CssClass != null ? settings.CssClass.Split(' ').ToList() : new List<string>(); 419 if (settings.Disabled) 420 { 421 attributes.Add("disabled", "true"); 422 classList.Add("disabled"); 423 } 424 425 if (!string.IsNullOrEmpty(settings.ConfirmText) || !string.IsNullOrEmpty(settings.ConfirmTitle)) 426 { 427 settings.Id = !string.IsNullOrEmpty(settings.Id) ? settings.Id : Guid.NewGuid().ToString("N"); 428 @RenderConfirmDialog(settings); 429 settings.OnClick = "document.getElementById('" + settings.Id + "ModalTrigger').checked = true"; 430 } 431 432 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 433 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 434 if (!string.IsNullOrEmpty(settings.AltText)) 435 { 436 attributes.Add("title", settings.AltText); 437 } 438 else if (!string.IsNullOrEmpty(settings.Title)) 439 { 440 attributes.Add("title", settings.Title); 441 } 442 443 var onClickEvents = new List<string>(); 444 if (!string.IsNullOrEmpty(settings.OnClick)) 445 { 446 onClickEvents.Add(settings.OnClick); 447 } 448 if (!string.IsNullOrEmpty(settings.Href)) 449 { 450 if (settings.Href.StartsWith("default.aspx", StringComparison.InvariantCultureIgnoreCase)) 451 { 452 settings.Href = "/" + settings.Href; 453 } 454 455 onClickEvents.Add("location.href='" + settings.Href + "'"); 456 } 457 if (onClickEvents.Count > 0) 458 { 459 attributes.Add("onClick", string.Join(";", onClickEvents)); 460 } 461 462 if (settings.ButtonLayout != ButtonLayout.None) 463 { 464 classList.Add("btn"); 465 string btnLayout = Enum.GetName(typeof(ButtonLayout), settings.ButtonLayout).ToLower(); 466 if (btnLayout == "linkclean") 467 { 468 btnLayout = "link-clean"; //fix 469 } 470 classList.Add("btn--" + btnLayout); 471 } 472 473 if (settings.Icon == null) 474 { 475 settings.Icon = new Icon(); 476 } 477 settings.Icon.Label = settings.Title; 478 479 attributes.Add("type", Enum.GetName(typeof(ButtonType), settings.ButtonType).ToLower()); 480 481 //If link is a paragraph, go to that paragraph 482 if (!string.IsNullOrEmpty(settings.Href) && settings.Href.Contains("#")) 483 { 484 string[] hrefSplit = settings.Href.Trim().Split('#'); 485 string idToScrollTo = "paragraph_" + hrefSplit[1].Trim(); 486 487 int pageId = Dynamicweb.Environment.Helpers.LinkHelper.GetInternalPageId(settings.Href.TrimStart('/')); 488 if (Pageview.ID == pageId) 489 { 490 attributes.Remove("onClick"); 491 attributes.Add("onClick", "document.getElementById('" + idToScrollTo + "').scrollIntoView({behavior: 'smooth'})"); 492 } 493 else if (pageId != 0) 494 { 495 settings.Href = hrefSplit[0].Trim() + "#paragraph_" + hrefSplit[1].Trim(); 496 attributes.Remove("onClick"); 497 attributes.Add("onClick", "location.href='" + settings.Href + "'"); 498 } 499 } 500 501 <button class="@string.Join(" ", classList) dw-mod" @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@Render(settings.Icon)</button> 502 } 503 } 504 505 @helper RenderConfirmDialog(Button settings) 506 { 507 Modal confirmDialog = new Modal 508 { 509 Id = settings.Id, 510 Width = ModalWidth.Sm, 511 Heading = new Heading 512 { 513 Level = 2, 514 Title = settings.ConfirmTitle 515 }, 516 BodyText = settings.ConfirmText 517 }; 518 519 confirmDialog.AddAction(new Button { Title = Translate("Cancel"), ButtonLayout = ButtonLayout.Secondary, OnClick = "document.getElementById('" + settings.Id + "ModalTrigger').checked = false"}); 520 confirmDialog.AddAction(new Button { Title = Translate("OK"), ButtonLayout = ButtonLayout.Primary, OnClick = "document.getElementById('" + settings.Id + "ModalTrigger').checked = false;" + settings.OnClick }); 521 522 @Render(confirmDialog) 523 } 524 @using Dynamicweb.Rapido.Blocks.Components.General 525 @using Dynamicweb.Rapido.Blocks.Components 526 @using Dynamicweb.Core 527 528 @helper RenderDashboard(Dashboard settings) 529 { 530 var widgets = settings.GetWidgets(); 531 532 if (!string.IsNullOrEmpty(settings.WidgetsBaseBackgroundColor)) 533 { 534 //set bg color for them 535 536 System.Drawing.Color color = System.Drawing.ColorTranslator.FromHtml(settings.WidgetsBaseBackgroundColor); 537 int r = Convert.ToInt16(color.R); 538 int g = Convert.ToInt16(color.G); 539 int b = Convert.ToInt16(color.B); 540 541 var count = widgets.Length; 542 var max = Math.Max(r, Math.Max(g, b)); 543 double step = 255.0 / (max * count); 544 var i = 0; 545 foreach (var widget in widgets) 546 { 547 i++; 548 549 var shade = "rgb(" + Converter.ToString(r * step * i).Replace(",", ".") + ", " + Converter.ToString(g * step * i).Replace(",", ".") + ", " + Converter.ToString(b * step * i).Replace(",", ".") + ")"; 550 widget.BackgroundColor = shade; 551 } 552 } 553 554 <div class="dashboard @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 555 @foreach (var widget in widgets) 556 { 557 <div class="dashboard__widget"> 558 @Render(widget) 559 </div> 560 } 561 </div> 562 } 563 @using Dynamicweb.Rapido.Blocks.Components.General 564 @using Dynamicweb.Rapido.Blocks.Components 565 566 @helper RenderDashboardWidgetLink(DashboardWidgetLink settings) 567 { 568 if (!string.IsNullOrEmpty(settings.Link)) 569 { 570 var backgroundStyles = ""; 571 if (!string.IsNullOrEmpty(settings.BackgroundColor)) 572 { 573 backgroundStyles = "style=\"background-color:" + settings.BackgroundColor + "\""; 574 } 575 576 <a href="@settings.Link" class="widget widget--link @settings.CssClass dw-mod" @backgroundStyles title="@settings.Title" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 577 <div class="u-center-middle u-color-light"> 578 @if (settings.Icon != null) 579 { 580 settings.Icon.CssClass += "widget__icon"; 581 @Render(settings.Icon) 582 } 583 <div class="widget__title">@settings.Title</div> 584 </div> 585 </a> 586 } 587 } 588 @using Dynamicweb.Rapido.Blocks.Components.General 589 @using Dynamicweb.Rapido.Blocks.Components 590 591 @helper RenderDashboardWidgetCounter(DashboardWidgetCounter settings) 592 { 593 var backgroundStyles = ""; 594 if (!string.IsNullOrEmpty(settings.BackgroundColor)) 595 { 596 backgroundStyles = "style='background-color:" + settings.BackgroundColor + "'"; 597 } 598 599 <div class="widget @settings.CssClass dw-mod" @backgroundStyles @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 600 <div class="u-center-middle u-color-light"> 601 @if (settings.Icon != null) 602 { 603 settings.Icon.CssClass += "widget__icon"; 604 @Render(settings.Icon) 605 } 606 <div class="widget__counter">@settings.Count</div> 607 <div class="widget__title">@settings.Title</div> 608 </div> 609 </div> 610 } 611 @using System.Reflection 612 @using Dynamicweb.Rapido.Blocks.Components.General 613 @using Dynamicweb.Rapido.Blocks.Components 614 @using Dynamicweb.Core 615 616 @* Component *@ 617 618 @helper RenderLink(Link settings) 619 { 620 if (settings != null && !string.IsNullOrEmpty(settings.Href) && (!string.IsNullOrEmpty(settings.Title) || settings.Icon != null)) 621 { 622 Dictionary<string, string> attributes = new Dictionary<string, string>(); 623 List<string> classList = settings.CssClass != null ? settings.CssClass.Split(' ').ToList() : new List<string>(); 624 if (settings.Disabled) 625 { 626 attributes.Add("disabled", "true"); 627 classList.Add("disabled"); 628 } 629 630 if (!string.IsNullOrEmpty(settings.AltText)) 631 { 632 attributes.Add("title", settings.AltText); 633 } 634 else if (!string.IsNullOrEmpty(settings.Title)) 635 { 636 attributes.Add("title", settings.Title); 637 } 638 639 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 640 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 641 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onClick", settings.OnClick); } 642 attributes.Add("href", settings.Href); 643 644 if (settings.ButtonLayout != ButtonLayout.None) 645 { 646 classList.Add("btn"); 647 string btnLayout = Enum.GetName(typeof(ButtonLayout), settings.ButtonLayout).ToLower(); 648 if (btnLayout == "linkclean") 649 { 650 btnLayout = "link-clean"; //fix 651 } 652 classList.Add("btn--" + btnLayout); 653 } 654 655 if (settings.Icon == null) 656 { 657 settings.Icon = new Icon(); 658 } 659 settings.Icon.Label = settings.Title; 660 661 if (settings.Target == LinkTargetType.Blank && settings.Rel == LinkRelType.None) 662 { 663 settings.Rel = LinkRelType.Noopener; 664 } 665 if (settings.Target != LinkTargetType.None) 666 { 667 attributes.Add("target", "_" + Enum.GetName(typeof(LinkTargetType), settings.Target).ToLower()); 668 } 669 if (settings.Download) 670 { 671 attributes.Add("download", "true"); 672 } 673 if (settings.Rel != LinkRelType.None) 674 { 675 attributes.Add("rel", Enum.GetName(typeof(LinkRelType), settings.Rel).ToLower()); 676 } 677 678 <a class="@string.Join(" ", classList) dw-mod" @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@Render(settings.Icon)</a> 679 } 680 } 681 @using System.Reflection 682 @using Dynamicweb.Rapido.Blocks.Components 683 @using Dynamicweb.Rapido.Blocks.Components.General 684 @using Dynamicweb.Rapido.Blocks 685 686 687 @* Component *@ 688 689 @helper RenderRating(Rating settings) 690 { 691 if (settings.Score > 0) 692 { 693 int rating = settings.Score; 694 string iconType = "fa-star"; 695 696 switch (settings.Type.ToString()) { 697 case "Stars": 698 iconType = "fa-star"; 699 break; 700 case "Hearts": 701 iconType = "fa-heart"; 702 break; 703 case "Lemons": 704 iconType = "fa-lemon"; 705 break; 706 case "Bombs": 707 iconType = "fa-bomb"; 708 break; 709 } 710 711 <div class="u-ta-right"> 712 @for (int i = 0; i < settings.OutOf; i++) 713 { 714 <i class="@(rating > i ? "fas" : "far") @iconType"></i> 715 } 716 </div> 717 } 718 } 719 @using System.Reflection 720 @using Dynamicweb.Rapido.Blocks.Components.General 721 @using Dynamicweb.Rapido.Blocks.Components 722 723 724 @* Component *@ 725 726 @helper RenderSelectFieldOption(SelectFieldOption settings) 727 { 728 Dictionary<string, string> attributes = new Dictionary<string, string>(); 729 if (settings.Checked) { attributes.Add("selected", "true"); } 730 if (settings.Disabled) { attributes.Add("disabled", "true"); } 731 if (settings.Value != null) { attributes.Add("value", settings.Value); } 732 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 733 734 <option @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@settings.Label</option> 735 } 736 @using System.Reflection 737 @using Dynamicweb.Rapido.Blocks.Components.General 738 @using Dynamicweb.Rapido.Blocks.Components 739 740 741 @* Component *@ 742 743 @helper RenderNavigation(Navigation settings) { 744 @RenderNavigation(new 745 { 746 id = settings.Id, 747 cssclass = settings.CssClass, 748 startLevel = settings.StartLevel, 749 endlevel = settings.EndLevel, 750 expandmode = settings.Expandmode, 751 sitemapmode = settings.SitemapMode, 752 template = settings.Template 753 }) 754 } 755 @using Dynamicweb.Rapido.Blocks.Components.General 756 @using Dynamicweb.Rapido.Blocks.Components 757 758 759 @* Component *@ 760 761 @helper RenderBreadcrumbNavigation(BreadcrumbNavigation settings) { 762 settings.Id = String.IsNullOrEmpty(settings.Id) ? "breadcrumb" : settings.Id; 763 settings.Template = String.IsNullOrEmpty(settings.Template) ? "Breadcrumb.xslt" : settings.Template; 764 settings.StartLevel = settings.StartLevel == 0 ? 1 : settings.StartLevel; 765 settings.EndLevel = settings.EndLevel == 10 ? 1 : settings.EndLevel; 766 settings.Expandmode = String.IsNullOrEmpty(settings.Expandmode) ? "all" : settings.Expandmode; 767 settings.SitemapMode = false; 768 769 @RenderNavigation(settings) 770 } 771 @using Dynamicweb.Rapido.Blocks.Components.General 772 @using Dynamicweb.Rapido.Blocks.Components 773 774 775 @* Component *@ 776 777 @helper RenderLeftNavigation(LeftNavigation settings) { 778 settings.Id = String.IsNullOrEmpty(settings.Id) ? "breadcrumb" : settings.Id; 779 settings.Template = String.IsNullOrEmpty(settings.Template) ? "Breadcrumb.xslt" : settings.Template; 780 settings.StartLevel = settings.StartLevel == 0 ? 1 : settings.StartLevel; 781 settings.EndLevel = settings.EndLevel == 10 ? 1 : settings.EndLevel; 782 settings.Expandmode = String.IsNullOrEmpty(settings.Expandmode) ? "all" : settings.Expandmode; 783 784 <div class="grid__cell"> 785 @RenderNavigation(settings) 786 </div> 787 } 788 @using System.Reflection 789 @using Dynamicweb.Rapido.Blocks.Components.General 790 @using Dynamicweb.Core 791 792 @* Component *@ 793 794 @helper RenderHeading(Heading settings) 795 { 796 if (settings != null && !string.IsNullOrEmpty(settings.Title)) 797 { 798 string color = settings.Color != null ? "style=\"color: " + settings.Color + "\"" : ""; 799 string tagName = settings.Level != 0 ? "h" + settings.Level.ToString() : "div"; 800 801 @("<" + tagName + " class=\"" + settings.CssClass + " dw-mod\" " + color + ">") 802 if (!string.IsNullOrEmpty(settings.Link)) 803 { 804 @Render(new Link { Href = settings.Link, Icon = settings.Icon, Title = settings.Title, ButtonLayout = ButtonLayout.None }) 805 } 806 else 807 { 808 if (settings.Icon == null) 809 { 810 settings.Icon = new Icon(); 811 } 812 settings.Icon.Label = settings.Title; 813 @Render(settings.Icon) 814 } 815 @("</" + tagName + ">"); 816 } 817 } 818 @using Dynamicweb.Rapido.Blocks.Components 819 @using Dynamicweb.Rapido.Blocks.Components.General 820 @using Dynamicweb.Rapido.Blocks 821 822 823 @* Component *@ 824 825 @helper RenderImage(Image settings) 826 { 827 string cleanImagePath = string.Empty; 828 if (settings.Path is string) 829 { 830 cleanImagePath = settings.Path; 831 } 832 int index = cleanImagePath.IndexOf("&x"); 833 if (index >= 0) 834 { 835 cleanImagePath = cleanImagePath.Substring(0, index); 836 } 837 838 if (settings.FilterPrimary != ImageFilter.None || settings.FilterSecondary != ImageFilter.None) 839 { 840 Dictionary<string, string> optionalAttributes = new Dictionary<string, string>(); 841 if (!string.IsNullOrEmpty(settings.FilterColor)) { optionalAttributes.Add("style", "background-color: " + settings.FilterColor); } 842 843 if (settings.Caption != null) 844 { 845 @:<div> 846 } 847 848 var primaryFilterClass = settings.FilterPrimary.ToString().ToLower(); 849 var secondaryFilterClass = settings.FilterSecondary.ToString().ToLower(); 850 851 <div class="image-filter image-filter--@primaryFilterClass u-position-relative dw-mod" @ComponentMethods.AddAttributes(optionalAttributes)> 852 <div class="image-filter image-filter--@secondaryFilterClass dw-mod"> 853 @if (settings.Link != null) 854 { 855 <a href="@settings.Link"> 856 @RenderTheImage(settings, cleanImagePath) 857 </a> 858 } 859 else 860 { 861 @RenderTheImage(settings, cleanImagePath) 862 } 863 </div> 864 </div> 865 866 if (settings.Caption != null) 867 { 868 <span class="image-caption dw-mod">@settings.Caption</span> 869 @:</div> 870 } 871 } 872 else 873 { 874 if (settings.Caption != null) 875 { 876 @:<div> 877 } 878 if (!string.IsNullOrEmpty(settings.Link)) 879 { 880 <a href="@settings.Link"> 881 @RenderTheImage(settings, cleanImagePath) 882 </a> 883 } 884 else 885 { 886 @RenderTheImage(settings, cleanImagePath) 887 } 888 889 if (settings.Caption != null) 890 { 891 <span class="image-caption dw-mod">@settings.Caption</span> 892 @:</div> 893 } 894 } 895 } 896 897 @helper RenderTheImage(Image settings, string cleanImagePath) 898 { 899 if (settings != null) 900 { 901 string placeholderImage = "/Files/Images/placeholder.gif"; 902 string imageEngine = "/Admin/Public/GetImage.ashx?"; 903 904 // CDN 905 var cdnUrl = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetString("CDNUrl"); 906 bool cdnActivate = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetBoolean("CDNActivate"); 907 if (!string.IsNullOrWhiteSpace(cdnUrl) && cdnActivate) 908 { 909 imageEngine = cdnUrl + imageEngine; 910 } 911 912 string imageStyle = ""; 913 914 switch (settings.Style) 915 { 916 case ImageStyle.Ball: 917 imageStyle = "grid__cell-img--ball"; 918 break; 919 920 case ImageStyle.Triangle: 921 imageStyle = "grid__cell-img--triangle"; 922 break; 923 } 924 925 if (settings.Style == ImageStyle.Ball || settings.Style == ImageStyle.Circle || settings.Style == ImageStyle.Triangle) 926 { 927 settings.ImageDefault.Crop = settings.ImageDefault.Crop == 5 ? settings.ImageDefault.Crop = 0 : settings.ImageDefault.Crop; 928 929 if (settings.ImageDefault != null) 930 { 931 settings.ImageDefault.Height = settings.ImageDefault.Width; 932 } 933 if (settings.ImageMedium != null) 934 { 935 settings.ImageMedium.Height = settings.ImageMedium.Width; 936 } 937 if (settings.ImageSmall != null) 938 { 939 settings.ImageSmall.Height = settings.ImageSmall.Width; 940 } 941 } 942 943 string defaultImage = imageEngine; 944 string imageSmall = ""; 945 string imageMedium = ""; 946 947 if (settings.DisableImageEngine) 948 { 949 defaultImage = settings.Path; 950 } 951 else 952 { 953 if (settings.ImageDefault != null) 954 { 955 defaultImage += Dynamicweb.Rapido.Services.Images.GetImagePathFromSettings(settings.ImageDefault); 956 957 if (settings.Path.GetType() != typeof(string)) 958 { 959 defaultImage += settings.Path != null ? "Image=" + settings.Path.PathUrlEncoded : ""; 960 defaultImage += settings.Path != null ? "&" + settings.Path.GetFocalPointParameters() : ""; 961 } 962 else 963 { 964 defaultImage += settings.Path != null ? "Image=" + settings.Path : ""; 965 } 966 } 967 968 if (settings.ImageSmall != null) 969 { 970 imageSmall = "data-src-small=\"" + imageEngine; 971 imageSmall += Dynamicweb.Rapido.Services.Images.GetImagePathFromSettings(settings.ImageSmall); 972 973 if (settings.Path.GetType() != typeof(string)) 974 { 975 imageSmall += settings.Path != null ? "Image=" + settings.Path.PathUrlEncoded : ""; 976 imageSmall += settings.Path != null ? "&" + settings.Path.GetFocalPointParameters() : ""; 977 } 978 else 979 { 980 imageSmall += settings.Path != null ? "Image=" + settings.Path : ""; 981 } 982 983 imageSmall += "\""; 984 } 985 986 if (settings.ImageMedium != null) 987 { 988 imageMedium = "data-src-medium=\"" + imageEngine; 989 imageMedium += Dynamicweb.Rapido.Services.Images.GetImagePathFromSettings(settings.ImageMedium); 990 991 if (settings.Path.GetType() != typeof(string)) 992 { 993 imageMedium += settings.Path != null ? "Image=" + settings.Path.PathUrlEncoded : ""; 994 imageMedium += settings.Path != null ? "&" + settings.Path.GetFocalPointParameters() : ""; 995 } 996 else 997 { 998 imageMedium += settings.Path != null ? "Image=" + settings.Path : ""; 999 } 1000 1001 imageMedium += "\""; 1002 } 1003 } 1004 1005 Dictionary<string, string> optionalAttributes = new Dictionary<string, string>(); 1006 if (cleanImagePath != null) 1007 { 1008 Dynamicweb.Content.Files.Metadata.Meta metadata = Dynamicweb.Content.Files.Metadata.EditorFactory.GetMetadataForFile(cleanImagePath); 1009 if (metadata != null) 1010 { 1011 string metaDataAlt = metadata.GetValue("alt"); 1012 optionalAttributes.Add("alt", metaDataAlt); 1013 } 1014 } 1015 if (!string.IsNullOrEmpty(settings.OnClick)) { optionalAttributes.Add("onclick", settings.OnClick); } 1016 if (!string.IsNullOrEmpty(settings.Title)) 1017 { 1018 optionalAttributes.Add("alt", settings.Title); 1019 optionalAttributes.Add("title", settings.Title); 1020 } 1021 1022 if (settings.DisableLazyLoad) 1023 { 1024 <img id="@settings.Id" class="@imageStyle @settings.CssClass dw-mod" src="@defaultImage" @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes) /> 1025 } 1026 else 1027 { 1028 <img id="@settings.Id" class="b-lazy @imageStyle @settings.CssClass dw-mod" src="@placeholderImage" data-src="@defaultImage" @imageSmall @imageMedium @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes) /> 1029 } 1030 } 1031 } 1032 @using System.Reflection 1033 @using Dynamicweb.Rapido.Blocks.Components.General 1034 @using Dynamicweb.Rapido.Blocks.Components 1035 1036 @* Component *@ 1037 1038 @helper RenderFileField(FileField settings) 1039 { 1040 var attributes = new Dictionary<string, string>(); 1041 if (string.IsNullOrEmpty(settings.Id)) 1042 { 1043 settings.Id = Guid.NewGuid().ToString("N"); 1044 } 1045 1046 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1047 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1048 if (settings.Required) { attributes.Add("required", "true"); } 1049 if (settings.Multiple) { attributes.Add("multiple", "true"); } 1050 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1051 if (string.IsNullOrEmpty(settings.ChooseFileText)) 1052 { 1053 settings.ChooseFileText = Translate("Choose file"); 1054 } 1055 if (string.IsNullOrEmpty(settings.NoFilesChosenText)) 1056 { 1057 settings.NoFilesChosenText = Translate("No files chosen..."); 1058 } 1059 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1060 1061 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1062 1063 string setValueToFakeInput = "FileUpload.setValueToFakeInput(this)"; 1064 attributes.Add("onchange", setValueToFakeInput + (!string.IsNullOrEmpty(settings.OnChange) ? settings.OnChange : "")); 1065 1066 attributes.Add("type", "file"); 1067 if (settings.Value != null) { attributes.Add("value", settings.Value); } 1068 settings.CssClass = "u-full-width " + settings.CssClass; 1069 1070 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1071 1072 <div class="form__field-group u-full-width @settings.WrapperCssClass dw-mod"> 1073 @if (!string.IsNullOrEmpty(settings.Label)) 1074 { 1075 <label for="@settings.Id">@settings.Label</label> 1076 } 1077 @if (!string.IsNullOrEmpty(settings.HelpText)) 1078 { 1079 <small class="form__help-text">@settings.HelpText</small> 1080 } 1081 1082 <div class="form__field-combi file-input u-no-margin dw-mod"> 1083 <input @ComponentMethods.AddAttributes(resultAttributes) class="file-input__real-input" data-no-files-text="@settings.NoFilesChosenText" data-many-files-text="@Translate("files")" /> 1084 <label for="@settings.Id" class="file-input__btn btn--secondary btn dw-mod">@settings.ChooseFileText</label> 1085 <label for="@settings.Id" class="@settings.CssClass file-input__fake-input js-fake-input dw-mod">@settings.NoFilesChosenText</label> 1086 @if (settings.UploadButton != null) 1087 { 1088 settings.UploadButton.CssClass += " btn--condensed u-no-margin"; 1089 @Render(settings.UploadButton) 1090 } 1091 </div> 1092 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1093 </div> 1094 } 1095 @using System.Reflection 1096 @using Dynamicweb.Rapido.Blocks.Components.General 1097 @using Dynamicweb.Rapido.Blocks.Components 1098 @using Dynamicweb.Core 1099 @using System.Linq 1100 1101 @* Component *@ 1102 1103 @helper RenderDateTimeField(DateTimeField settings) 1104 { 1105 if (string.IsNullOrEmpty(settings.Id)) 1106 { 1107 settings.Id = Guid.NewGuid().ToString("N"); 1108 } 1109 1110 var textField = new TextField { 1111 Name = settings.Name, 1112 Id = settings.Id, 1113 Label = settings.Label, 1114 HelpText = settings.HelpText, 1115 Value = settings.Value, 1116 Disabled = settings.Disabled, 1117 Required = settings.Required, 1118 ErrorMessage = settings.ErrorMessage, 1119 CssClass = settings.CssClass, 1120 WrapperCssClass = settings.WrapperCssClass, 1121 OnChange = settings.OnChange, 1122 OnClick = settings.OnClick, 1123 ExtraAttributes = settings.ExtraAttributes, 1124 // 1125 Placeholder = settings.Placeholder 1126 }; 1127 1128 @Render(textField) 1129 1130 List<string> jsAttributes = new List<string>(); 1131 1132 jsAttributes.Add("mode: '" + Enum.GetName(typeof(DateTimeFieldMode), settings.Mode).ToLower() + "'"); 1133 1134 if (!string.IsNullOrEmpty(settings.DateFormat)) 1135 { 1136 jsAttributes.Add("dateFormat: '" + settings.DateFormat + "'"); 1137 } 1138 if (!string.IsNullOrEmpty(settings.MinDate)) 1139 { 1140 jsAttributes.Add("minDate: '" + settings.MinDate + "'"); 1141 } 1142 if (!string.IsNullOrEmpty(settings.MaxDate)) 1143 { 1144 jsAttributes.Add("maxDate: '" + settings.MaxDate + "'"); 1145 } 1146 if (settings.IsInline) 1147 { 1148 jsAttributes.Add("inline: " + Converter.ToString(settings.IsInline).ToLower()); 1149 } 1150 if (settings.EnableTime) 1151 { 1152 jsAttributes.Add("enableTime: " + Converter.ToString(settings.EnableTime).ToLower()); 1153 } 1154 if (settings.EnableWeekNumbers) 1155 { 1156 jsAttributes.Add("weekNumbers: " + Converter.ToString(settings.EnableWeekNumbers).ToLower()); 1157 } 1158 1159 jsAttributes.AddRange(settings.GetFlatPickrOptions().Select(x => x.Key + ": " + x.Value)); 1160 1161 <script> 1162 document.addEventListener("DOMContentLoaded", function () { 1163 flatpickr("#@textField.Id", { 1164 @string.Join(",", jsAttributes) 1165 }); 1166 }); 1167 </script> 1168 } 1169 @using System.Reflection 1170 @using Dynamicweb.Rapido.Blocks.Components.General 1171 @using Dynamicweb.Rapido.Blocks.Components 1172 1173 @* Component *@ 1174 1175 @helper RenderTextField(TextField settings) 1176 { 1177 var attributes = new Dictionary<string, string>(); 1178 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1179 { 1180 settings.Id = Guid.NewGuid().ToString("N"); 1181 } 1182 1183 /*base settings*/ 1184 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1185 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1186 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1187 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1188 if (settings.Required) { attributes.Add("required", "true"); } 1189 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1190 /*end*/ 1191 1192 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); } 1193 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); } 1194 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); } 1195 if (settings.ReadOnly) { attributes.Add("readonly", "true"); } 1196 if (settings.MaxLength != 0) { attributes.Add("maxlength", settings.MaxLength.ToString()); } 1197 if (!string.IsNullOrEmpty(settings.Placeholder)) { attributes.Add("placeholder", settings.Placeholder); } 1198 attributes.Add("type", Enum.GetName(typeof(TextFieldType), settings.Type).ToLower()); 1199 if (settings.Type == TextFieldType.Password) { attributes.Add("autocomplete", "off"); }; 1200 if (settings.Value != null) { attributes.Add("value", settings.Value); } 1201 1202 settings.CssClass = "u-full-width " + settings.CssClass; 1203 1204 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1205 1206 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1207 1208 string noMargin = "u-no-margin"; 1209 if (!settings.ReadOnly) { 1210 noMargin = ""; 1211 } 1212 1213 <div class="form__field-group u-full-width @noMargin @settings.WrapperCssClass dw-mod"> 1214 @if (!string.IsNullOrEmpty(settings.Label)) 1215 { 1216 <label for="@settings.Id">@settings.Label</label> 1217 } 1218 @if (!string.IsNullOrEmpty(settings.HelpText)) 1219 { 1220 <small class="form__help-text">@settings.HelpText</small> 1221 } 1222 1223 @if (settings.ActionButton != null) 1224 { 1225 settings.ActionButton.CssClass += " btn--condensed u-no-margin"; 1226 <div class="form__field-combi u-no-margin dw-mod"> 1227 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1228 @Render(settings.ActionButton) 1229 </div> 1230 } 1231 else 1232 { 1233 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1234 } 1235 1236 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1237 </div> 1238 } 1239 @using System.Reflection 1240 @using Dynamicweb.Rapido.Blocks.Components.General 1241 @using Dynamicweb.Rapido.Blocks.Components 1242 1243 @* Component *@ 1244 1245 @helper RenderNumberField(NumberField settings) 1246 { 1247 var attributes = new Dictionary<string, string>(); 1248 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1249 { 1250 settings.Id = Guid.NewGuid().ToString("N"); 1251 } 1252 1253 /*base settings*/ 1254 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1255 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1256 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1257 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1258 if (settings.Required) { attributes.Add("required", "true"); } 1259 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1260 /*end*/ 1261 1262 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); } 1263 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); } 1264 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); } 1265 if (settings.ReadOnly) { attributes.Add("readonly", "true"); } 1266 if (settings.Max != null) { attributes.Add("max", settings.Max.ToString()); } 1267 if (settings.Min != null) { attributes.Add("min", settings.Min.ToString()); } 1268 if (settings.Step != 0) { attributes.Add("step", settings.Step.ToString()); } 1269 if (settings.Value != null && !string.IsNullOrEmpty(settings.Value.ToString())) { attributes.Add("value", settings.Value.ToString()); } 1270 attributes.Add("type", "number"); 1271 1272 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1273 1274 <div class="form__field-group u-full-width @settings.WrapperCssClass dw-mod"> 1275 @if (!string.IsNullOrEmpty(settings.Label)) 1276 { 1277 <label for="@settings.Id">@settings.Label</label> 1278 } 1279 @if (!string.IsNullOrEmpty(settings.HelpText)) 1280 { 1281 <small class="form__help-text">@settings.HelpText</small> 1282 } 1283 1284 @if (settings.ActionButton != null) 1285 { 1286 settings.ActionButton.CssClass += " btn--condensed u-no-margin"; 1287 <div class="form__field-combi u-no-margin dw-mod"> 1288 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1289 @Render(settings.ActionButton) 1290 </div> 1291 } 1292 else 1293 { 1294 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1295 } 1296 1297 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1298 </div> 1299 } 1300 @using System.Reflection 1301 @using Dynamicweb.Rapido.Blocks.Components.General 1302 @using Dynamicweb.Rapido.Blocks.Components 1303 1304 1305 @* Component *@ 1306 1307 @helper RenderTextareaField(TextareaField settings) 1308 { 1309 Dictionary<string, string> attributes = new Dictionary<string, string>(); 1310 string id = settings.Id; 1311 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(id)) 1312 { 1313 id = Guid.NewGuid().ToString("N"); 1314 } 1315 1316 if (!string.IsNullOrEmpty(id)) { attributes.Add("id", id); } 1317 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1318 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); } 1319 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); } 1320 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); } 1321 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1322 if (!string.IsNullOrEmpty(settings.Placeholder)) { attributes.Add("placeholder", settings.Placeholder); } 1323 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1324 if (settings.Required) { attributes.Add("required", "true"); } 1325 if (settings.ReadOnly) { attributes.Add("readonly", "true"); } 1326 if (settings.MaxLength != 0) { attributes.Add("maxlength", settings.MaxLength.ToString()); } 1327 if (settings.Rows != 0) { attributes.Add("rows", settings.Rows.ToString()); } 1328 attributes.Add("name", settings.Name); 1329 1330 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1331 1332 <div class="form__field-group @settings.WrapperCssClass dw-mod"> 1333 @if (!string.IsNullOrEmpty(settings.Label)) 1334 { 1335 <label for="@id">@settings.Label</label> 1336 } 1337 @if (!string.IsNullOrEmpty(settings.HelpText)) 1338 { 1339 <small class="form__help-text">@settings.HelpText</small> 1340 } 1341 1342 <textarea class="u-full-width @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)>@settings.Value</textarea> 1343 1344 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1345 </div> 1346 } 1347 @using System.Reflection 1348 @using Dynamicweb.Rapido.Blocks.Components.General 1349 @using Dynamicweb.Rapido.Blocks.Components 1350 1351 1352 @* Component *@ 1353 1354 @helper RenderHiddenField(HiddenField settings) { 1355 var attributes = new Dictionary<string, string>(); 1356 attributes.Add("type", "hidden"); 1357 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1358 if (settings.Value != null) { attributes.Add("value", settings.Value); } 1359 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1360 1361 <input @ComponentMethods.AddAttributes(attributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)/> 1362 } 1363 @using System.Reflection 1364 @using Dynamicweb.Rapido.Blocks.Components.General 1365 @using Dynamicweb.Rapido.Blocks.Components 1366 1367 @* Component *@ 1368 1369 @helper RenderCheckboxField(CheckboxField settings) 1370 { 1371 var attributes = new Dictionary<string, string>(); 1372 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1373 { 1374 settings.Id = Guid.NewGuid().ToString("N"); 1375 } 1376 1377 /*base settings*/ 1378 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1379 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1380 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1381 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1382 if (settings.Required) { attributes.Add("required", "true"); } 1383 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1384 /*end*/ 1385 1386 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1387 1388 attributes.Add("type", "checkbox"); 1389 if (settings.Checked) { attributes.Add("checked", "true"); } 1390 settings.CssClass = "form__control " + settings.CssClass; 1391 if (settings.Value != null) { attributes.Add("value", settings.Value); } 1392 1393 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1394 1395 <div class="form__field-group @settings.WrapperCssClass dw-mod"> 1396 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1397 @if (!string.IsNullOrEmpty(settings.Label)) 1398 { 1399 <label for="@settings.Id" class="dw-mod">@settings.Label</label> 1400 } 1401 @if (!string.IsNullOrEmpty(settings.HelpText)) 1402 { 1403 <small class="form__help-text">@settings.HelpText</small> 1404 } 1405 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1406 </div> 1407 } 1408 @using System.Reflection 1409 @using Dynamicweb.Rapido.Blocks.Components.General 1410 @using Dynamicweb.Rapido.Blocks.Components 1411 1412 1413 @* Component *@ 1414 1415 @helper RenderCheckboxListField(CheckboxListField settings) 1416 { 1417 <div class="form__field-group @settings.WrapperCssClass u-margin-bottom dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 1418 @if (!string.IsNullOrEmpty(settings.Label)) 1419 { 1420 <label>@settings.Label</label> 1421 } 1422 @if (!string.IsNullOrEmpty(settings.HelpText)) 1423 { 1424 <small class="form__help-text">@settings.HelpText</small> 1425 } 1426 1427 @foreach (var item in settings.Options) 1428 { 1429 if (settings.Required) 1430 { 1431 item.Required = true; 1432 } 1433 if (settings.Disabled) 1434 { 1435 item.Disabled = true; 1436 } 1437 if (!string.IsNullOrEmpty(settings.Name)) 1438 { 1439 item.Name = settings.Name; 1440 } 1441 if (!string.IsNullOrEmpty(settings.CssClass)) 1442 { 1443 item.CssClass += settings.CssClass; 1444 } 1445 1446 /* value is not supported */ 1447 1448 if (!string.IsNullOrEmpty(settings.OnClick)) 1449 { 1450 item.OnClick += settings.OnClick; 1451 } 1452 if (!string.IsNullOrEmpty(settings.OnChange)) 1453 { 1454 item.OnChange += settings.OnChange; 1455 } 1456 @Render(item) 1457 } 1458 1459 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1460 </div> 1461 } 1462 @using Dynamicweb.Rapido.Blocks.Components.General 1463 1464 @* Component *@ 1465 1466 @helper RenderSearch(Search settings) 1467 { 1468 var searchValue = HttpContext.Current.Request.QueryString.Get(settings.SearchParameter) ?? ""; 1469 var groupValue = HttpContext.Current.Request.QueryString.Get(settings.GroupsParameter) ?? ""; 1470 1471 if (string.IsNullOrEmpty(settings.Id)) 1472 { 1473 settings.Id = Guid.NewGuid().ToString("N"); 1474 } 1475 1476 var resultAttributes = new Dictionary<string, string>(); 1477 1478 if (settings.PageSize != 0) 1479 { 1480 resultAttributes.Add("data-page-size", settings.PageSize.ToString()); 1481 } 1482 if (!string.IsNullOrEmpty(settings.GroupItemsFeedUrl)) 1483 { 1484 resultAttributes.Add("data-groups-feed-url", settings.GroupItemsFeedUrl); 1485 if (!string.IsNullOrEmpty(groupValue)) 1486 { 1487 resultAttributes.Add("data-selected-group", groupValue); 1488 } 1489 if (!string.IsNullOrEmpty(settings.GroupsParameter)) 1490 { 1491 resultAttributes.Add("data-groups-parameter", settings.GroupsParameter); 1492 } 1493 } 1494 resultAttributes.Add("data-force-init", "true"); 1495 if (settings.GoToFirstSearchResultOnEnter) 1496 { 1497 resultAttributes.Add("data-go-to-first-search-result-on-enter", settings.GoToFirstSearchResultOnEnter.ToString().ToLower()); 1498 } 1499 if (!string.IsNullOrEmpty(settings.SearchParameter)) 1500 { 1501 resultAttributes.Add("data-search-parameter", settings.SearchParameter); 1502 } 1503 resultAttributes.Add("data-search-feed-url", settings.SearchData.SearchFeedUrl); 1504 resultAttributes.Add("data-results-template-id", settings.SearchData.ResultsTemplateId); 1505 1506 if (settings.SecondSearchData != null) 1507 { 1508 resultAttributes.Add("data-second-search-feed-url", settings.SecondSearchData.SearchFeedUrl); 1509 resultAttributes.Add("data-second-results-template-id", settings.SecondSearchData.ResultsTemplateId); 1510 } 1511 if (!string.IsNullOrEmpty(settings.ResultsPageUrl)) 1512 { 1513 resultAttributes.Add("data-results-page-url", settings.ResultsPageUrl); 1514 } 1515 1516 resultAttributes = resultAttributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1517 1518 string searchFieldCss = (settings.SearchButton == null) ? "search--with-icon" : ""; 1519 1520 <div class="search @settings.CssClass @searchFieldCss js-search-data-source dw-mod" id="@settings.Id" @ComponentMethods.AddAttributes(resultAttributes)> 1521 @if (!string.IsNullOrEmpty(settings.GroupItemsFeedUrl)) 1522 { 1523 <button type="button" class="search__groups-btn dw-mod js-search-groups-btn">@Translate("All")</button> 1524 <ul class="dropdown dropdown--absolute-position dw-mod search__groups-results js-search-groups-list"></ul> 1525 } 1526 1527 <input type="text" class="search__field dw-mod js-search-field" placeholder="@settings.Placeholder" value="@searchValue"> 1528 1529 <div class="dropdown dropdown--absolute-position search__results dw-mod js-search-results @(settings.SecondSearchData != null ? "search__results--combined" : "")"> 1530 @if (settings.SecondSearchData != null) 1531 { 1532 <div class="search__column search__column--products dw-mod"> 1533 <div class="search__column-header dw-mod">@Translate("Products")</div> 1534 <ul class="search__results-list dw-mod js-search-results-list" id="@(settings.Id)_ResultsList"></ul> 1535 @if (!string.IsNullOrEmpty(settings.SearchData.ResultsPageUrl)) 1536 { 1537 @Render(new Link { 1538 Title = Translate("View all"), 1539 CssClass = "js-view-all-button u-margin", 1540 Href = settings.SearchData.ResultsPageUrl 1541 }); 1542 } 1543 </div> 1544 <div class="search__column search__column--pages dw-mod"> 1545 <div class="search__column-header">@Translate("Pages")</div> 1546 <ul class="search__results-list dw-mod js-search-results-second-list" id="@(settings.Id)_SecondResultsList"></ul> 1547 @if (!string.IsNullOrEmpty(settings.SecondSearchData.ResultsPageUrl)) 1548 { 1549 @Render(new Link 1550 { 1551 Title = Translate("View all"), 1552 CssClass = "js-view-all-button u-margin", 1553 Href = settings.SecondSearchData.ResultsPageUrl 1554 }); 1555 } 1556 </div> 1557 } 1558 else 1559 { 1560 <div class="search__column search__column--only dw-mod"> 1561 <ul class="search__results-list dw-mod js-search-results-list" id="@(settings.Id)_ResultsList"></ul> 1562 @if (!string.IsNullOrEmpty(settings.SearchData.ResultsPageUrl)) 1563 { 1564 @Render(new Link { 1565 Title = Translate("View all"), 1566 CssClass = "js-view-all-button u-margin", 1567 Href = settings.SearchData.ResultsPageUrl 1568 }); 1569 } 1570 </div> 1571 } 1572 </div> 1573 1574 @if (settings.SearchButton != null) 1575 { 1576 settings.SearchButton.CssClass += " search__btn js-search-btn"; 1577 if (settings.RenderDefaultSearchIcon) 1578 { 1579 settings.SearchButton.Icon = new Icon { Name = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SearchIcon").SelectedValue }; 1580 } 1581 @Render(settings.SearchButton); 1582 } 1583 </div> 1584 } 1585 @using System.Reflection 1586 @using Dynamicweb.Rapido.Blocks.Components.General 1587 @using Dynamicweb.Rapido.Blocks.Components 1588 1589 1590 @* Component *@ 1591 1592 @helper RenderSelectField(SelectField settings) 1593 { 1594 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1595 { 1596 settings.Id = Guid.NewGuid().ToString("N"); 1597 } 1598 1599 <div class="form__field-group u-full-width @settings.WrapperCssClass dw-mod"> 1600 @if (!string.IsNullOrEmpty(settings.Label)) 1601 { 1602 <label for="@settings.Id">@settings.Label</label> 1603 } 1604 @if (!string.IsNullOrEmpty(settings.HelpText)) 1605 { 1606 <small class="form__help-text">@settings.HelpText</small> 1607 } 1608 1609 @if (settings.ActionButton != null) 1610 { 1611 settings.ActionButton.CssClass += " btn--condensed u-no-margin"; 1612 <div class="form__field-combi u-no-margin dw-mod"> 1613 @RenderSelectBase(settings) 1614 @Render(settings.ActionButton) 1615 </div> 1616 } 1617 else 1618 { 1619 @RenderSelectBase(settings) 1620 } 1621 1622 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1623 </div> 1624 } 1625 1626 @helper RenderSelectBase(SelectField settings) 1627 { 1628 var attributes = new Dictionary<string, string>(); 1629 1630 /*base settings*/ 1631 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1632 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1633 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1634 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1635 if (settings.Required) { attributes.Add("required", "true"); } 1636 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1637 /*end*/ 1638 1639 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1640 1641 <select @ComponentMethods.AddAttributes(resultAttributes) class="u-full-width @settings.CssClass dw-mod"> 1642 @if (settings.Default != null) 1643 { 1644 @Render(settings.Default) 1645 } 1646 1647 @foreach (var item in settings.Options) 1648 { 1649 if (settings.Value != null) { 1650 item.Checked = item.Value == settings.Value; 1651 } 1652 @Render(item) 1653 } 1654 </select> 1655 } 1656 @using System.Reflection 1657 @using Dynamicweb.Rapido.Blocks.Components.General 1658 @using Dynamicweb.Rapido.Blocks.Components 1659 1660 @* Component *@ 1661 1662 @helper RenderRadioButtonField(RadioButtonField settings) 1663 { 1664 var attributes = new Dictionary<string, string>(); 1665 if (!string.IsNullOrEmpty(settings.Label) && string.IsNullOrEmpty(settings.Id)) 1666 { 1667 settings.Id = Guid.NewGuid().ToString("N"); 1668 } 1669 1670 /*base settings*/ 1671 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1672 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 1673 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 1674 if (settings.Disabled) { attributes.Add("disabled", "true"); } 1675 if (settings.Required) { attributes.Add("required", "true"); } 1676 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 1677 /*end*/ 1678 1679 attributes.Add("type", "radio"); 1680 if (settings.Checked) { attributes.Add("checked", "true"); } 1681 settings.CssClass = "form__control " + settings.CssClass; 1682 if (settings.Value != null) { attributes.Add("value", settings.Value); } 1683 1684 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 1685 1686 <div class="form__field-group @settings.WrapperCssClass dw-mod"> 1687 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 1688 @if (!string.IsNullOrEmpty(settings.Label)) 1689 { 1690 <label for="@settings.Id" class="dw-mod">@settings.Label</label> 1691 } 1692 @if (!string.IsNullOrEmpty(settings.HelpText)) 1693 { 1694 <small class="form__help-text">@settings.HelpText</small> 1695 } 1696 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1697 </div> 1698 } 1699 @using System.Reflection 1700 @using Dynamicweb.Rapido.Blocks.Components.General 1701 @using Dynamicweb.Rapido.Blocks.Components 1702 1703 1704 @* Component *@ 1705 1706 @helper RenderRadioButtonListField(RadioButtonListField settings) 1707 { 1708 if (settings.Required && !String.IsNullOrEmpty(settings.Label)) { settings.Label += " <span class=\"required dw-mod\">*</span>"; } 1709 1710 <div class="form__field-group @settings.WrapperCssClass u-margin-bottom dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 1711 @if (!string.IsNullOrEmpty(settings.Label)) 1712 { 1713 <label>@settings.Label</label> 1714 } 1715 @if (!string.IsNullOrEmpty(settings.HelpText)) 1716 { 1717 <small class="form__help-text">@settings.HelpText</small> 1718 } 1719 1720 @foreach (var item in settings.Options) 1721 { 1722 if (settings.Required) 1723 { 1724 item.Required = true; 1725 } 1726 if (settings.Disabled) 1727 { 1728 item.Disabled = true; 1729 } 1730 if (!string.IsNullOrEmpty(settings.Name)) 1731 { 1732 item.Name = settings.Name; 1733 } 1734 if (settings.Value != null && settings.Value == item.Value) 1735 { 1736 item.Checked = true; 1737 } 1738 if (!string.IsNullOrEmpty(settings.OnClick)) 1739 { 1740 item.OnClick += settings.OnClick; 1741 } 1742 if (!string.IsNullOrEmpty(settings.OnChange)) 1743 { 1744 item.OnChange += settings.OnChange; 1745 } 1746 if (!string.IsNullOrEmpty(settings.CssClass)) 1747 { 1748 item.CssClass += settings.CssClass; 1749 } 1750 @Render(item) 1751 } 1752 1753 @Render(new NotificationMessage { Message = settings.ErrorMessage }) 1754 </div> 1755 } 1756 @using System.Reflection 1757 @using Dynamicweb.Rapido.Blocks.Components.General 1758 @using Dynamicweb.Rapido.Blocks.Components 1759 1760 1761 @* Component *@ 1762 1763 @helper RenderNotificationMessage(NotificationMessage settings) 1764 { 1765 if (!string.IsNullOrEmpty(settings.Message)) 1766 { 1767 var attributes = new Dictionary<string, string>(); 1768 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 1769 1770 string messageTypeClass = Enum.GetName(typeof(NotificationMessageType), settings.MessageType).ToLower(); 1771 <div class="field-@messageTypeClass @settings.CssClass u-full-width dw-mod" @ComponentMethods.AddAttributes(attributes)>@settings.Message</div> 1772 } 1773 } 1774 @using Dynamicweb.Rapido.Blocks.Components.General 1775 1776 1777 @* Component *@ 1778 1779 @helper RenderHandlebarsRoot(HandlebarsRoot settings) { 1780 string preRender = !String.IsNullOrEmpty(settings.PreRenderScriptTemplate) ? "data-pre-render-template=\"" + settings.PreRenderScriptTemplate + "\"" : ""; 1781 1782 <div class="@settings.CssClass dw-mod js-handlebars-root" id="@settings.Id" data-template="@settings.ScriptTemplate" data-json-feed="@settings.FeedUrl" data-init-onload="@settings.InitOnLoad.ToString()" data-preloader="@settings.Preloader" @preRender> 1783 @if (settings.SubBlocks != null) { 1784 @RenderBlockList(settings.SubBlocks) 1785 } 1786 </div> 1787 } 1788 @using System.Reflection 1789 @using Dynamicweb.Rapido.Blocks.Components.General 1790 @using Dynamicweb.Rapido.Blocks.Components 1791 @using System.Text.RegularExpressions 1792 1793 @* Component *@ 1794 1795 @helper RenderSticker(Sticker settings) 1796 { 1797 if (!String.IsNullOrEmpty(settings.Title)) 1798 { 1799 string size = settings.Size.ToString() != "None" ? "" + "stickers-container__tag--" + settings.Size.ToString().ToLower() : ""; 1800 string style = settings.Style.ToString() != "None" ? "" + "stickers-container__tag--" + settings.Style.ToString().ToLower() : ""; 1801 1802 Dictionary<String, String> optionalAttributes = new Dictionary<string, string>(); 1803 if (!String.IsNullOrEmpty(settings.Color) || !String.IsNullOrEmpty(settings.BackgroundColor)) 1804 { 1805 string styleTag = !String.IsNullOrEmpty(settings.Color) ? "color: " + settings.Color + "; " : ""; 1806 styleTag += !String.IsNullOrEmpty(settings.BackgroundColor) ? "background-color: " + settings.BackgroundColor + "; " : ""; 1807 optionalAttributes.Add("style", styleTag); 1808 } 1809 1810 <div class="stickers-container__tag @size @style @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 1811 @if (settings.CssClass?.Contains("js-render-savings-prefix") ?? false) 1812 { 1813 <span class="sale-sticker-savings-prefix js-sale-sticker-savings-prefix"></span> 1814 <span class="sale-sticker-savings">@settings.Title</span> 1815 } 1816 else 1817 { 1818 @settings.Title 1819 } 1820 </div> 1821 } 1822 } 1823 1824 @using System.Reflection 1825 @using Dynamicweb.Rapido.Blocks.Components.General 1826 @using Dynamicweb.Rapido.Blocks.Components 1827 1828 1829 @* Component *@ 1830 1831 @helper RenderStickersCollection(StickersCollection settings) 1832 { 1833 if (settings.Stickers.Count > 0) 1834 { 1835 string position = "stickers-container--" + Regex.Replace(settings.Position.ToString(), "([a-z])([A-Z])", "$1-$2").ToLower(); 1836 1837 <div class="stickers-container @position @settings.CssClass dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 1838 @foreach (Sticker sticker in settings.Stickers) 1839 { 1840 @Render(sticker) 1841 } 1842 </div> 1843 } 1844 } 1845 1846 @using Dynamicweb.Rapido.Blocks.Components.General 1847 1848 1849 @* Component *@ 1850 1851 @helper RenderForm(Form settings) { 1852 if (settings != null) 1853 { 1854 Dictionary<string, string> optionalAttributes = new Dictionary<string, string>(); 1855 if (!string.IsNullOrEmpty(settings.Action)) { optionalAttributes.Add("action", settings.Action); }; 1856 if (!string.IsNullOrEmpty(settings.Name)) { optionalAttributes.Add("name", settings.Name); }; 1857 if (!string.IsNullOrEmpty(settings.OnSubmit)) { optionalAttributes.Add("onsubmit", settings.OnSubmit); }; 1858 var enctypes = new Dictionary<string, string> 1859 { 1860 { "multipart", "multipart/form-data" }, 1861 { "text", "text/plain" }, 1862 { "application", "application/x-www-form-urlencoded" } 1863 }; 1864 if (settings.Enctype != FormEnctype.none) { optionalAttributes.Add("enctype", enctypes[Enum.GetName(typeof(FormEnctype), settings.Enctype).ToLower()]); }; 1865 optionalAttributes.Add("method", settings.Method.ToString()); 1866 1867 if (!string.IsNullOrEmpty(settings.FormStartMarkup)) 1868 { 1869 @settings.FormStartMarkup 1870 } 1871 else 1872 { 1873 @:<form class="@settings.CssClass u-no-margin dw-mod" @ComponentMethods.AddAttributes(optionalAttributes) @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 1874 } 1875 1876 foreach (var field in settings.GetFields()) 1877 { 1878 @Render(field) 1879 } 1880 1881 @:</form> 1882 } 1883 } 1884 @using System.Reflection 1885 @using Dynamicweb.Rapido.Blocks.Components.General 1886 @using Dynamicweb.Rapido.Blocks.Components 1887 1888 1889 @* Component *@ 1890 1891 @helper RenderText(Text settings) 1892 { 1893 @settings.Content 1894 } 1895 @using System.Reflection 1896 @using Dynamicweb.Rapido.Blocks.Components.General 1897 @using Dynamicweb.Rapido.Blocks.Components 1898 1899 1900 @* Component *@ 1901 1902 @helper RenderContentModule(ContentModule settings) { 1903 if (!string.IsNullOrEmpty(settings.Content)) 1904 { 1905 @settings.Content 1906 } 1907 } 1908 @using System.Reflection 1909 @using Dynamicweb.Rapido.Blocks.Components.General 1910 @using Dynamicweb.Rapido.Blocks.Components 1911 1912 1913 @* Component *@ 1914 1915 @helper RenderModal(Modal settings) { 1916 if (settings != null) 1917 { 1918 string modalId = !string.IsNullOrEmpty(settings.Id) ? settings.Id : Guid.NewGuid().ToString("N"); 1919 1920 string onchange = !string.IsNullOrEmpty(settings.OnClose) ? "onchange=\"if(!this.checked){" + settings.OnClose + "}\"" : ""; 1921 1922 <input type="checkbox" id="@(modalId)ModalTrigger" class="modal-trigger" @onchange /> 1923 1924 <div class="modal-container"> 1925 @if (!settings.DisableDarkOverlay) 1926 { 1927 <label for="@(modalId)ModalTrigger" id="@(modalId)ModalOverlay" class="modal-overlay"></label> 1928 } 1929 <div class="modal modal--@settings.Width.ToString().ToLower() modal-height--@settings.Height.ToString().ToLower()" id="@(modalId)Modal"> 1930 @if (settings.Heading != null) 1931 { 1932 if (!string.IsNullOrEmpty(settings.Heading.Title)) 1933 { 1934 <div class="modal__header"> 1935 @Render(settings.Heading) 1936 </div> 1937 } 1938 } 1939 <div class="modal__body @(settings.Width.ToString().ToLower() == "full" ? "modal__body--full" : "")"> 1940 @if (!string.IsNullOrEmpty(settings.BodyText)) 1941 { 1942 @settings.BodyText 1943 } 1944 @if (settings.BodyTemplate != null) 1945 { 1946 @settings.BodyTemplate 1947 } 1948 @{ 1949 var actions = settings.GetActions(); 1950 } 1951 </div> 1952 @if (actions.Length > 0) 1953 { 1954 <div class="modal__footer"> 1955 @foreach (var action in actions) 1956 { 1957 if (Pageview.Device.ToString() != "Mobile") { 1958 action.CssClass += " u-no-margin"; 1959 } else { 1960 action.CssClass += " u-full-width u-margin-bottom"; 1961 } 1962 1963 @Render(action) 1964 } 1965 </div> 1966 } 1967 <label class="modal__close-btn js-modal-close-btn" for="@(modalId)ModalTrigger"></label> 1968 </div> 1969 </div> 1970 } 1971 } 1972 @using Dynamicweb.Rapido.Blocks.Components.General 1973 1974 @* Component *@ 1975 1976 @helper RenderMediaListItem(MediaListItem settings) 1977 { 1978 <div class="media-list-item @settings.CssClass dw-mod" @(!string.IsNullOrEmpty(settings.Id) ? "id=\"" + settings.Id + "\"" : "")> 1979 @if (!string.IsNullOrEmpty(settings.Label)) 1980 { 1981 if (!string.IsNullOrEmpty(settings.Link)) 1982 { 1983 @Render(new Link 1984 { 1985 Href = settings.Link, 1986 CssClass = "media-list-item__sticker dw-mod", 1987 ButtonLayout = ButtonLayout.None, 1988 Title = settings.Label, 1989 OnClick = !string.IsNullOrEmpty(settings.OnClick) ? settings.OnClick : "" 1990 }) 1991 } 1992 else if (!string.IsNullOrEmpty(settings.OnClick)) 1993 { 1994 <span class="media-list-item__sticker dw-mod" onclick="@(settings.OnClick)"> 1995 <span class="u-uppercase">@settings.Label</span> 1996 </span> 1997 } 1998 else 1999 { 2000 <span class="media-list-item__sticker media-list-item__sticker--no-link dw-mod"> 2001 <span class="u-uppercase">@settings.Label</span> 2002 </span> 2003 } 2004 } 2005 <div class="media-list-item__wrap"> 2006 <div class="media-list-item__info dw-mod"> 2007 <div class="media-list-item__header dw-mod"> 2008 @if (!string.IsNullOrEmpty(settings.Title)) 2009 { 2010 if (!string.IsNullOrEmpty(settings.Link)) 2011 { 2012 @Render(new Link 2013 { 2014 Href = settings.Link, 2015 CssClass = "media-list-item__name dw-mod", 2016 ButtonLayout = ButtonLayout.None, 2017 Title = settings.Title, 2018 OnClick = !string.IsNullOrEmpty(settings.OnClick) ? settings.OnClick : "" 2019 }) 2020 } 2021 else if (!string.IsNullOrEmpty(settings.OnClick)) 2022 { 2023 <span class="media-list-item__name dw-mod" onclick="@(settings.OnClick)">@settings.Title</span> 2024 } 2025 else 2026 { 2027 <span class="media-list-item__name media-list-item__name--no-link dw-mod">@settings.Title</span> 2028 } 2029 } 2030 2031 @if (!string.IsNullOrEmpty(settings.Status)) 2032 { 2033 <div class="media-list-item__state dw-mod">@settings.Status</div> 2034 } 2035 </div> 2036 @{ 2037 settings.InfoTable.CssClass += " media-list-item__parameters-table"; 2038 } 2039 2040 @Render(settings.InfoTable) 2041 </div> 2042 <div class="media-list-item__actions dw-mod"> 2043 <div class="media-list-item__actions-list dw-mod"> 2044 @{ 2045 var actions = settings.GetActions(); 2046 2047 foreach (ButtonBase action in actions) 2048 { 2049 action.ButtonLayout = ButtonLayout.None; 2050 action.CssClass += " media-list-item__action link"; 2051 2052 @Render(action) 2053 } 2054 } 2055 </div> 2056 2057 @if (settings.SelectButton != null && !string.IsNullOrEmpty(settings.SelectButton.Title)) 2058 { 2059 settings.SelectButton.CssClass += " u-no-margin"; 2060 2061 <div class="media-list-item__action-button"> 2062 @Render(settings.SelectButton) 2063 </div> 2064 } 2065 </div> 2066 </div> 2067 </div> 2068 } 2069 @using Dynamicweb.Rapido.Blocks.Components.General 2070 @using Dynamicweb.Rapido.Blocks.Components 2071 2072 @helper RenderTable(Table settings) 2073 { 2074 Dictionary<string, string> attributes = new Dictionary<string, string>(); 2075 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 2076 2077 var enumToClasses = new Dictionary<TableDesign, string> 2078 { 2079 { TableDesign.Clean, "table--clean" }, 2080 { TableDesign.Bordered, "table--bordered" }, 2081 { TableDesign.Striped, "table--striped" }, 2082 { TableDesign.Hover, "table--hover" }, 2083 { TableDesign.Compact, "table--compact" }, 2084 { TableDesign.Condensed, "table--condensed" }, 2085 { TableDesign.NoTopBorder, "table--no-top-border" } 2086 }; 2087 string tableDesignClass = ""; 2088 if (settings.Design != TableDesign.None) 2089 { 2090 tableDesignClass = enumToClasses[settings.Design]; 2091 } 2092 2093 if (!string.IsNullOrEmpty(settings.CssClass) || settings.Design != TableDesign.None) { attributes.Add("class", "table " + tableDesignClass + " " + settings.CssClass + " dw-mod"); } 2094 2095 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.Last().Value); 2096 2097 <table @ComponentMethods.AddAttributes(resultAttributes)> 2098 @if (settings.Header != null) 2099 { 2100 <thead> 2101 @Render(settings.Header) 2102 </thead> 2103 } 2104 <tbody> 2105 @foreach (var row in settings.Rows) 2106 { 2107 @Render(row) 2108 } 2109 </tbody> 2110 @if (settings.Footer != null) 2111 { 2112 <tfoot> 2113 @Render(settings.Footer) 2114 </tfoot> 2115 } 2116 </table> 2117 } 2118 @using Dynamicweb.Rapido.Blocks.Components.General 2119 @using Dynamicweb.Rapido.Blocks.Components 2120 2121 @helper RenderTableRow(TableRow settings) 2122 { 2123 Dictionary<string, string> attributes = new Dictionary<string, string>(); 2124 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 2125 2126 var enumToClasses = new Dictionary<TableRowDesign, string> 2127 { 2128 { TableRowDesign.NoBorder, "table__row--no-border" }, 2129 { TableRowDesign.Border, "table__row--border" }, 2130 { TableRowDesign.TopBorder, "table__row--top-line" }, 2131 { TableRowDesign.BottomBorder, "table__row--bottom-line" }, 2132 { TableRowDesign.Solid, "table__row--solid" } 2133 }; 2134 2135 string tableRowDesignClass = ""; 2136 if (settings.Design != TableRowDesign.None) 2137 { 2138 tableRowDesignClass = enumToClasses[settings.Design]; 2139 } 2140 2141 if (!string.IsNullOrEmpty(settings.CssClass) || settings.Design != TableRowDesign.None) { attributes.Add("class", "table__row " + tableRowDesignClass + " " + settings.CssClass + " dw-mod"); } 2142 2143 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.Last().Value); 2144 2145 <tr @ComponentMethods.AddAttributes(resultAttributes)> 2146 @foreach (var cell in settings.Cells) 2147 { 2148 if (settings.IsHeaderRow) 2149 { 2150 cell.IsHeader = true; 2151 } 2152 @Render(cell) 2153 } 2154 </tr> 2155 } 2156 @using Dynamicweb.Rapido.Blocks.Components.General 2157 @using Dynamicweb.Rapido.Blocks.Components 2158 @using Dynamicweb.Core 2159 2160 @helper RenderTableCell(TableCell settings) 2161 { 2162 Dictionary<string, string> attributes = new Dictionary<string, string>(); 2163 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 2164 if (settings.Colspan != 0) { attributes.Add("colspan", Converter.ToString(settings.Colspan)); } 2165 if (settings.Rowspan != 0) { attributes.Add("rowspan", Converter.ToString(settings.Rowspan)); } 2166 if (!string.IsNullOrEmpty(settings.CssClass)) { attributes.Add("class", settings.CssClass + " dw-mod"); } 2167 2168 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.Last().Value); 2169 2170 string tagName = settings.IsHeader ? "th" : "td"; 2171 2172 @("<" + tagName + " " + ComponentMethods.AddAttributes(resultAttributes) + ">") 2173 @settings.Content 2174 @("</" + tagName + ">"); 2175 } 2176 @using System.Linq 2177 @using Dynamicweb.Rapido.Blocks.Components.General 2178 2179 @* Component *@ 2180 2181 @helper RenderPagination(Dynamicweb.Rapido.Blocks.Components.General.Pagination settings) 2182 { 2183 var pageNumberQueryStringName = Dynamicweb.Rapido.Services.Pagination.GetPageNumberQueryStringName(settings); // Get the proper 'page number' query string parameter 2184 var queryParameters = Dynamicweb.Rapido.Services.Url.GetQueryParameters(pageNumberQueryStringName); // Get the NameValueCollection from the querystring 2185 2186 if (settings.NumberOfPages > 1) 2187 { 2188 string url = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + "/Default.aspx"; 2189 string ariaLabel = !string.IsNullOrWhiteSpace(settings.AriaLabel) ? settings.AriaLabel : Translate("Page navigation"); 2190 Dictionary<string, int> startAndEndPageNumber = Dynamicweb.Rapido.Services.Pagination.GetStartAndEndPageNumber(settings); 2191 2192 <div class="pager u-margin-top dw-mod @settings.CssClass" aria-label="@ariaLabel"> 2193 @if (settings.ShowPagingInfo) 2194 { 2195 <div class="pager__info dw-mod"> 2196 @Translate("Page") @settings.CurrentPageNumber @Translate("of") @settings.NumberOfPages 2197 </div> 2198 } 2199 <ul class="pager__list dw-mod"> 2200 @if (!string.IsNullOrWhiteSpace(settings.FirstPageUrl) && settings.ShowFirstAndLastControls) 2201 { 2202 @Render(new PaginationItem { Link = settings.FirstPageUrl, Icon = settings.FirstIcon }) 2203 } 2204 @if (!string.IsNullOrWhiteSpace(settings.PreviousPageUrl) && settings.ShowNextAndPrevControls) 2205 { 2206 @Render(new PaginationItem { Link = settings.PreviousPageUrl, Icon = settings.PrevIcon }) 2207 } 2208 @if (settings.GetPages().Any()) 2209 { 2210 foreach (var page in settings.GetPages()) 2211 { 2212 @Render(page) 2213 } 2214 } 2215 else 2216 { 2217 for (var page = startAndEndPageNumber["StartPage"]; page <= startAndEndPageNumber["EndPage"]; page++) 2218 { 2219 queryParameters = Dynamicweb.Rapido.Services.Url.UpdateQueryStringParameter(queryParameters, pageNumberQueryStringName, page.ToString()); 2220 @Render(new PaginationItem { Label = page.ToString(), Link = Dynamicweb.Rapido.Services.Url.BuildUri(url, queryParameters).PathAndQuery, IsActive = (settings.CurrentPageNumber == page) }); 2221 } 2222 } 2223 @if (!string.IsNullOrWhiteSpace(settings.NextPageUrl) && settings.ShowNextAndPrevControls) 2224 { 2225 @Render(new PaginationItem { Link = settings.NextPageUrl, Icon = settings.NextIcon }) 2226 } 2227 @if (!string.IsNullOrWhiteSpace(settings.LastPageUrl) && settings.ShowFirstAndLastControls) 2228 { 2229 @Render(new PaginationItem { Link = settings.LastPageUrl, Icon = settings.LastIcon }) 2230 } 2231 </ul> 2232 </div> 2233 } 2234 } 2235 2236 @helper RenderPaginationItem(PaginationItem settings) 2237 { 2238 if (settings.Icon == null) 2239 { 2240 settings.Icon = new Icon(); 2241 } 2242 2243 settings.Icon.Label = settings.Label; 2244 <li class="pager__btn dw-mod"> 2245 @if (settings.IsActive) 2246 { 2247 <span class="pager__num pager__num--current dw-mod"> 2248 @Render(settings.Icon) 2249 </span> 2250 } 2251 else 2252 { 2253 <a href="@settings.Link" class="pager__num dw-mod"> 2254 @Render(settings.Icon) 2255 </a> 2256 } 2257 </li> 2258 } 2259 2260 2261 @using Dynamicweb.Rapido.Blocks.Components.General 2262 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 2263 2264 2265 @using Dynamicweb.Frontend 2266 @using System.Reflection 2267 @using Dynamicweb.Content.Items 2268 @using System.Web.UI.HtmlControls 2269 @using Dynamicweb.Rapido.Blocks.Components 2270 @using Dynamicweb.Rapido.Blocks 2271 @using Dynamicweb.Rapido.Blocks.Components.Articles 2272 2273 @* Components for the articles *@ 2274 @using System.Reflection 2275 @using Dynamicweb.Rapido.Blocks.Components.Articles 2276 2277 2278 @* Component for the articles *@ 2279 2280 @helper RenderArticleBanner(dynamic settings) { 2281 string filterClasses = "image-filter image-filter--darken"; 2282 settings.Layout = ArticleHeaderLayout.Banner; 2283 2284 if (settings.Image != null) 2285 { 2286 if (settings.Image.Path != null) 2287 { 2288 <section class="multiple-paragraphs-container u-color-light paragraph-container--full-width"> 2289 <div class="background-image @filterClasses dw-mod"> 2290 <div class="background-image__wrapper @filterClasses dw-mod"> 2291 @{ 2292 settings.Image.CssClass += "background-image__cover dw-mod"; 2293 } 2294 @Render(settings.Image) 2295 </div> 2296 </div> 2297 <div class="center-container dw-mod"> 2298 <div class="grid"> 2299 <div class="grid__col-md-8 grid__col-xs-12 paragraph-container paragraph-container--height-lg"> 2300 <div class="u-left-middle"> 2301 <div> 2302 @if (!String.IsNullOrEmpty(settings.Heading)) 2303 { 2304 <h1 class="article__header article__header--giant dw-mod" style="color: @settings.TextColor">@settings.Heading</h1> 2305 } 2306 @if (!String.IsNullOrEmpty(settings.Subheading)) 2307 { 2308 <div class="article__leadtext dw-mod" style="color: @settings.TextColor">@settings.Subheading</div> 2309 } 2310 @if (!String.IsNullOrEmpty(settings.Author) || !String.IsNullOrEmpty(settings.Date)) 2311 { 2312 <small class="article__post-info u-margin-bottom--lg dw-mod" style="color: @settings.TextColor">@settings.Author @settings.Date</small> 2313 } 2314 @if (!String.IsNullOrEmpty(settings.Link)) { 2315 <div class="grid__cell"> 2316 @Render(new Link { Href = settings.Link, Title = settings.LinkText, ButtonLayout = settings.ButtonLayout }) 2317 </div> 2318 } 2319 </div> 2320 </div> 2321 </div> 2322 @if (settings.ExternalParagraphId != 0) 2323 { 2324 <div class="grid__col-md-4 grid__col-sm-12 grid__col-xs-12 paragraph-container paragraph-container--height-auto dw-mod"> 2325 <div class="u-color-light-gray--bg u-color-dark dw-mod"> 2326 @RenderParagraphContent(settings.ExternalParagraphId) 2327 </div> 2328 </div> 2329 } 2330 2331 </div> 2332 </div> 2333 </section> 2334 if (!String.IsNullOrEmpty(settings.Image.Caption)) { 2335 <div class="image-caption dw-mod">@settings.Image.Caption</div> 2336 } 2337 } 2338 else 2339 { 2340 settings.Layout = ArticleHeaderLayout.Clean; 2341 @RenderArticleCleanHeader(settings); 2342 } 2343 } 2344 else 2345 { 2346 settings.Layout = ArticleHeaderLayout.Clean; 2347 @RenderArticleCleanHeader(settings); 2348 } 2349 } 2350 @using System.Reflection 2351 @using Dynamicweb.Rapido.Blocks.Components 2352 @using Dynamicweb.Rapido.Blocks.Components.General 2353 @using Dynamicweb.Rapido.Blocks.Components.Articles 2354 @using Dynamicweb.Rapido.Blocks 2355 2356 2357 @* Component for the articles *@ 2358 2359 @helper RenderArticleHeader(ArticleHeader settings) { 2360 dynamic[] methodParameters = new dynamic[1]; 2361 methodParameters[0] = settings; 2362 MethodInfo customMethod = this.GetType().GetMethod("RenderArticleHeaderCustom"); 2363 2364 if (customMethod != null) 2365 { 2366 @customMethod.Invoke(this, methodParameters).ToString(); 2367 } else { 2368 switch (settings.Layout) 2369 { 2370 case ArticleHeaderLayout.Clean: 2371 @RenderArticleCleanHeader(settings); 2372 break; 2373 case ArticleHeaderLayout.Split: 2374 @RenderArticleSplitHeader(settings); 2375 break; 2376 case ArticleHeaderLayout.Banner: 2377 @RenderArticleBannerHeader(settings); 2378 break; 2379 case ArticleHeaderLayout.Overlay: 2380 @RenderArticleOverlayHeader(settings); 2381 break; 2382 default: 2383 @RenderArticleCleanHeader(settings); 2384 break; 2385 } 2386 } 2387 } 2388 2389 @helper RenderArticleCleanHeader(ArticleHeader settings) { 2390 dynamic[] methodParameters = new dynamic[1]; 2391 methodParameters[0] = settings; 2392 MethodInfo customMethod = this.GetType().GetMethod("RenderArticleCleanHeaderCustom"); 2393 2394 if (customMethod != null) 2395 { 2396 @customMethod.Invoke(this, methodParameters).ToString(); 2397 } 2398 else 2399 { 2400 string contentColumns = settings.TextLayout != ArticleHeaderTextLayout.Full ? "8" : "12"; 2401 2402 <div class="grid grid--align-content-start grid--justify-start"> 2403 <div class="grid__col-md-@contentColumns grid__col-sm-12 u-padding--lg dw-mod"> 2404 @if (!String.IsNullOrEmpty(settings.Category) || !String.IsNullOrEmpty(settings.Author) || !String.IsNullOrEmpty(settings.Date) || settings.RatingOutOf != 0) 2405 { 2406 <div class="u-border-bottom u-padding-bottom"> 2407 @if (!String.IsNullOrEmpty(settings.Category)) 2408 { 2409 <div class="u-pull--left"> 2410 <div class="article__category dw-mod" style="color: @settings.CategoryColor">@settings.Category</div> 2411 </div> 2412 } 2413 <div class="u-pull--right"> 2414 @if (!String.IsNullOrEmpty(settings.Author) || !String.IsNullOrEmpty(settings.Date)) 2415 { 2416 <small class="article__post-info dw-mod">@settings.Author @settings.Date</small> 2417 } 2418 @if (settings.RatingOutOf != 0) 2419 { 2420 @Render(new Rating { Score = settings.RatingScore, OutOf = settings.RatingOutOf }) 2421 } 2422 </div> 2423 </div> 2424 } 2425 2426 <div class="grid__cell"> 2427 @if (!String.IsNullOrEmpty(settings.Heading)) 2428 { 2429 <h1 class="article__header article__header--giant dw-mod">@settings.Heading</h1> 2430 } 2431 @if (settings.Image != null) 2432 { 2433 if (settings.Image.Path != null) 2434 { 2435 <div class="u-padding-bottom--lg"> 2436 @Render(settings.Image) 2437 </div> 2438 } 2439 } 2440 @if (!String.IsNullOrEmpty(settings.Subheading)) 2441 { 2442 <div class="article__leadtext dw-mod">@settings.Subheading</div> 2443 } 2444 @if (!String.IsNullOrEmpty(settings.Link)) 2445 { 2446 <div class="grid__cell"> 2447 @Render(new Link { Href = settings.Link, Title = settings.LinkText, ButtonLayout = settings.ButtonLayout }) 2448 </div> 2449 } 2450 </div> 2451 </div> 2452 @if (settings.ExternalParagraphId != 0) 2453 { 2454 <div class="grid__col-md-4 grid__col-sm-12 u-padding--lg u-color-light-gray--bg dw-mod"> 2455 @RenderParagraphContent(settings.ExternalParagraphId) 2456 </div> 2457 } 2458 </div> 2459 } 2460 } 2461 2462 @helper RenderArticleSplitHeader(ArticleHeader settings) { 2463 dynamic[] methodParameters = new dynamic[1]; 2464 methodParameters[0] = settings; 2465 MethodInfo customMethod = this.GetType().GetMethod("RenderArticleSplitHeaderCustom"); 2466 2467 if (customMethod != null) 2468 { 2469 @customMethod.Invoke(this, methodParameters).ToString(); 2470 } 2471 else 2472 { 2473 string headerColumnWidth = settings.ExternalParagraphId != 0 ? "4" : "6"; 2474 2475 if (settings.Image != null) 2476 { 2477 if (settings.Image.Path != null) 2478 { 2479 <section class="multiple-paragraphs-container paragraph-container--full-width"> 2480 <div class="grid"> 2481 <div class="grid__col-md-@headerColumnWidth grid__col-sm-12 grid__col-xs-12 paragraph-container paragraph-container--height-xl dw-mod"> 2482 <div class="u-left-middle u-padding--lg"> 2483 <div> 2484 @if (!String.IsNullOrEmpty(settings.Category)) 2485 { 2486 <div class="article__category dw-mod" style="color: @settings.CategoryColor">@settings.Category</div> 2487 } 2488 @if (!String.IsNullOrEmpty(settings.Heading)) 2489 { 2490 <h1 class="article__header article__header--giant dw-mod">@settings.Heading</h1> 2491 } 2492 @if (!String.IsNullOrEmpty(settings.Subheading)) 2493 { 2494 <div class="article__leadtext dw-mod">@settings.Subheading</div> 2495 } 2496 @if (!String.IsNullOrEmpty(settings.Author) || !String.IsNullOrEmpty(settings.Date)) 2497 { 2498 <small class="article__post-info u-pull--left dw-mod">@settings.Author @settings.Date</small> 2499 } 2500 @if (settings.RatingOutOf != 0) 2501 { 2502 <div class="u-pull--right"> 2503 @Render(new Rating { Score = settings.RatingScore, OutOf = settings.RatingOutOf }) 2504 </div> 2505 } 2506 @if (!String.IsNullOrEmpty(settings.Link)) { 2507 <div class="u-full-width u-pull--left u-margin-top"> 2508 @Render(new Link { Href = settings.Link, Title = settings.LinkText, ButtonLayout = settings.ButtonLayout }) 2509 </div> 2510 } 2511 </div> 2512 </div> 2513 </div> 2514 <div class="grid__col-md-@headerColumnWidth grid__col-sm-12 grid__col-xs-12 paragraph-container paragraph-container--height-auto dw-mod" style="background-image:url(/Admin/Public/GetImage.ashx?width=1800&amp;height=1100&amp;crop=0&amp;Compression=85&amp;DoNotUpscale=true&amp;image=@settings.Image.Path); background-position: center center; background-size: cover;"></div> 2515 @if (settings.ExternalParagraphId != 0) 2516 { 2517 <div class="grid__col-md-4 grid__col-sm-12 grid__col-xs-12 paragraph-container paragraph-container--height-auto u-color-light-gray--bg dw-mod"> 2518 @RenderParagraphContent(settings.ExternalParagraphId) 2519 </div> 2520 } 2521 </div> 2522 </section> 2523 } 2524 } 2525 else 2526 { 2527 @RenderArticleCleanHeader(settings); 2528 } 2529 } 2530 } 2531 2532 @helper RenderArticleOverlayHeader(ArticleHeader settings) { 2533 dynamic[] methodParameters = new dynamic[1]; 2534 methodParameters[0] = settings; 2535 MethodInfo customMethod = this.GetType().GetMethod("RenderArticleOverlayHeaderCustom"); 2536 2537 if (customMethod != null) 2538 { 2539 @customMethod.Invoke(this, methodParameters).ToString(); 2540 } 2541 else 2542 { 2543 string contentColumns = settings.TextLayout != ArticleHeaderTextLayout.Full ? "8" : "12"; 2544 string contentAlignment = settings.TextLayout == ArticleHeaderTextLayout.Center ? "grid--justify-center" : ""; 2545 2546 if (settings.Image != null) 2547 { 2548 if (settings.Image.Path != null) 2549 { 2550 if (settings.ExternalParagraphId == 0) 2551 { 2552 <section class="multiple-paragraphs-container u-color-light paragraph-container--full-width"> 2553 <div class="background-image image-filter image-filter--darken dw-mod"> 2554 <div class="background-image__wrapper image-filter image-filter--darken dw-mod"> 2555 @{ 2556 settings.Image.CssClass += "background-image__cover dw-mod"; 2557 } 2558 @Render(settings.Image) 2559 </div> 2560 </div> 2561 <div class="center-container dw-mod"> 2562 <div class="grid @contentAlignment"> 2563 <div class="grid__col-md-@contentColumns grid__col-xs-12 paragraph-container paragraph-container--height-xl u-no-padding dw-mod"> 2564 @if (!String.IsNullOrEmpty(settings.Heading)) 2565 { 2566 <h1 class="article__header article__header--giant u-padding-top--lg dw-mod" style="color: @settings.TextColor">@settings.Heading</h1> 2567 } 2568 @if (!String.IsNullOrEmpty(settings.Subheading)) 2569 { 2570 <div class="article__leadtext dw-mod" style="color: @settings.TextColor">@settings.Subheading</div> 2571 } 2572 <div class="u-margin-top"> 2573 @if (!String.IsNullOrEmpty(settings.Author) || !String.IsNullOrEmpty(settings.Date)) 2574 { 2575 <small class="article__post-info u-pull--left dw-mod" style="color: @settings.TextColor">@settings.Author @settings.Date</small> 2576 } 2577 @if (settings.RatingOutOf != 0) 2578 { 2579 <div class="u-pull--right"> 2580 @Render(new Rating { Score = settings.RatingScore, OutOf = settings.RatingOutOf }) 2581 </div> 2582 } 2583 </div> 2584 @if (!String.IsNullOrEmpty(settings.Link)) 2585 { 2586 <div class="grid__cell"> 2587 @Render(new Link { Href = settings.Link, Title = settings.LinkText, ButtonLayout = settings.ButtonLayout }) 2588 </div> 2589 } 2590 </div> 2591 </div> 2592 </div> 2593 </section> 2594 } 2595 else 2596 { 2597 @RenderArticleBanner(settings); 2598 } 2599 } 2600 } 2601 else 2602 { 2603 @RenderArticleCleanHeader(settings); 2604 } 2605 } 2606 } 2607 2608 @helper RenderArticleBannerHeader(dynamic settings) { 2609 dynamic[] methodParameters = new dynamic[1]; 2610 methodParameters[0] = settings; 2611 MethodInfo customMethod = this.GetType().GetMethod("RenderArticleBannerHeaderCustom"); 2612 2613 if (customMethod != null) 2614 { 2615 @customMethod.Invoke(this, methodParameters).ToString(); 2616 } 2617 else 2618 { 2619 @RenderArticleBanner(settings); 2620 } 2621 } 2622 @using System.Reflection 2623 @using System.Text.RegularExpressions; 2624 @using Dynamicweb.Frontend 2625 @using Dynamicweb.Content.Items 2626 @using Dynamicweb.Rapido.Blocks.Components 2627 @using Dynamicweb.Rapido.Blocks.Components.Articles 2628 @using Dynamicweb.Rapido.Blocks 2629 2630 @using Dynamicweb.Content.Items; 2631 @using Dynamicweb.Core 2632 2633 @functions { 2634 public class Author 2635 { 2636 public string Name; 2637 public string Image; 2638 public string Description; 2639 public string Date; 2640 } 2641 2642 public Author GetAuthor(Item item = null) 2643 { 2644 var author = new Author(); 2645 2646 var pageView = Dynamicweb.Frontend.PageView.Current(); 2647 var currPageItem = Dynamicweb.Content.Services.Pages.GetPage(pageView.ID)?.Item; 2648 2649 if (currPageItem == null) return null; 2650 2651 var authorItem = item ?? Item.GetItemById("AuthorItem", Converter.ToString(currPageItem["SpAuthor"])); 2652 2653 if (authorItem == null || authorItem["Author"] == null) return null; 2654 2655 var authorUrl = Converter.ToString(authorItem["Author"]); 2656 var authorDate = Converter.ToDateTime(authorItem["Date"]); 2657 2658 if (string.IsNullOrWhiteSpace(authorUrl)) return null; 2659 2660 var authorPageId = authorUrl.Contains("=") ? Converter.ToInt32(authorUrl.Substring(authorUrl.LastIndexOf('=') + 1)) : Converter.ToInt32(authorUrl); 2661 var authorPage = Dynamicweb.Content.Services.Pages.GetPage(authorPageId); 2662 2663 if (authorPage == null) return null; 2664 2665 var imgPrefix = "/Admin/Public/GetImage.ashx?width=200&height=200&Compression=99&Quality=99&Format=Webp&Crop=5&image="; 2666 2667 author.Name = authorPage.GetDisplayName(); 2668 author.Image = imgPrefix + Converter.ToString(authorPage.Item["Image"]); 2669 author.Description = Converter.ToString(authorPage.Item["Description"]); 2670 2671 if (string.IsNullOrWhiteSpace(Converter.ToString(authorItem["Date"]))) return author; 2672 2673 var month = pageView.Area.CultureInfo.DateTimeFormat.GetMonthName(authorDate.Month); 2674 author.Date = $"{authorDate.Day}. {month} {authorDate.Year}"; 2675 2676 return author; 2677 } 2678 } 2679 2680 @* Component for the articles *@ 2681 2682 @helper RenderArticleBodyRow(ArticleBodyRow settings) 2683 { 2684 string position = settings.TopLayout == "overlay" ? "article__overlay-offset" : ""; 2685 string contentAlignment = settings.TextLayout == "center" ? "grid--justify-center" : ""; 2686 var author = GetAuthor(); 2687 2688 if (author != null) 2689 { 2690 <div class="author-container"> 2691 <div class="author"> 2692 <p class="author-desc">@author.Description</p> 2693 <div class="author-wrapper"> 2694 <img src="@author.Image" class="author-img" alt="@HttpUtility.HtmlAttributeEncode(author.Name)" /> 2695 <div class="author-info"> 2696 <span class="author-name">@author.Name</span> 2697 <span class="author-divider @(string.IsNullOrWhiteSpace(author.Date) ? "u-hidden" : "")">|</span> 2698 <span class="author-date">@author.Date</span> 2699 </div> 2700 </div> 2701 </div> 2702 </div> 2703 } 2704 2705 <div class="grid grid--align-content-start @contentAlignment @position dw-mod"> 2706 @RenderBlockList(settings.SubBlocks) 2707 </div> 2708 } 2709 @using System.Reflection 2710 @using Dynamicweb.Rapido.Blocks.Components 2711 @using Dynamicweb.Rapido.Blocks.Components.General 2712 @using Dynamicweb.Rapido.Blocks.Components.Articles 2713 @using Dynamicweb.Rapido.Blocks 2714 2715 @* Component for the articles *@ 2716 2717 @helper RenderArticleImage(ArticleImage settings) 2718 { 2719 if (settings.Image != null) 2720 { 2721 if (settings.Image.Path != null) 2722 { 2723 <div class="u-margin-bottom--lg"> 2724 @Render(settings.Image) 2725 </div> 2726 } 2727 } 2728 } 2729 @using System.Reflection 2730 @using Dynamicweb.Rapido.Blocks.Components 2731 @using Dynamicweb.Rapido.Blocks.Components.Articles 2732 2733 2734 @* Component for the articles *@ 2735 2736 @helper RenderArticleSubHeader(ArticleSubHeader settings) 2737 { 2738 if (!String.IsNullOrEmpty(settings.Title)) 2739 { 2740 <h2 class="article__header">@settings.Title</h2> 2741 } 2742 } 2743 @using System.Reflection 2744 @using Dynamicweb.Rapido.Blocks.Components 2745 @using Dynamicweb.Rapido.Blocks.Components.Articles 2746 @using Dynamicweb.Rapido.Blocks 2747 2748 2749 @* Component for the articles *@ 2750 2751 @helper RenderArticleText(ArticleText settings) 2752 { 2753 if (!String.IsNullOrEmpty(settings.Text)) 2754 { 2755 string greatTextClass = settings.EnableLargeText == true ? "article__paragraph--great-text" : ""; 2756 2757 <div class="article__paragraph @greatTextClass"> 2758 @settings.Text 2759 </div> 2760 } 2761 } 2762 @using System.Reflection 2763 @using Dynamicweb.Rapido.Blocks.Components 2764 @using Dynamicweb.Rapido.Blocks.Components.Articles 2765 @using Dynamicweb.Rapido.Blocks 2766 2767 2768 @* Component for the articles *@ 2769 2770 @helper RenderArticleQuote(ArticleQuote settings) 2771 { 2772 string text = Regex.Replace(settings.Text, "<.*?>", String.Empty); 2773 2774 <div class="grid u-padding-bottom--lg"> 2775 @if (settings.Image != null) 2776 { 2777 if (settings.Image.Path != null) { 2778 <div class="grid__col-3"> 2779 <div class="grid__cell-img"> 2780 @{ 2781 settings.Image.Title = !String.IsNullOrEmpty(settings.Image.Title) ? settings.Image.Title : settings.Author; 2782 settings.Image.CssClass += " article__image article__image--ball"; 2783 settings.Image.ImageDefault.Width = 200; 2784 settings.Image.ImageDefault.Height = 200; 2785 } 2786 @Render(settings.Image) 2787 </div> 2788 </div> 2789 } 2790 } 2791 <div class="grid__col-auto"> 2792 @if (!String.IsNullOrEmpty(settings.Text)) 2793 { 2794 <div class="article__quote dw-mod"> 2795 <i class="fas fa-quote-right u-margin-bottom--lg"></i> 2796 @settings.Text 2797 <i class="fas fa-quote-right"></i> 2798 </div> 2799 } 2800 @if (!String.IsNullOrEmpty(settings.Author)) 2801 { 2802 <div class="article__quote-author dw-mod"> 2803 - @settings.Author 2804 </div> 2805 } 2806 </div> 2807 </div> 2808 } 2809 @using System.Reflection 2810 @using Dynamicweb.Rapido.Blocks.Components 2811 @using Dynamicweb.Rapido.Blocks.Components.Articles 2812 @using Dynamicweb.Rapido.Blocks 2813 2814 @* Component for the articles *@ 2815 2816 @helper RenderArticleInfoTable(ArticleInfoTable settings) 2817 { 2818 <table class="table table--clean"> 2819 @foreach (var row in settings.Rows) 2820 { 2821 string iconColor = row.IconColor != null ? row.IconColor : "u-brand-color-two"; 2822 2823 <tr> 2824 @if (!String.IsNullOrEmpty(row.Icon)) 2825 { 2826 <td class="u-w32px"><i class="@row.Icon fa-2x @row.IconColor"></i></td> 2827 } 2828 <td class="u-no-margin-on-p-elements"> 2829 <div class="u-bold">@row.Title</div> 2830 @if (!String.IsNullOrEmpty(row.SubTitle)) 2831 { 2832 if (row.Link == null) 2833 { 2834 <div>@row.SubTitle</div> 2835 } 2836 else 2837 { 2838 <a href="@row.Link" class="u-color-inherit">@row.SubTitle</a> 2839 } 2840 } 2841 </td> 2842 </tr> 2843 } 2844 </table> 2845 } 2846 @using System.Reflection 2847 @using Dynamicweb.Rapido.Blocks.Components 2848 @using Dynamicweb.Rapido.Blocks.Components.General 2849 @using Dynamicweb.Rapido.Blocks.Components.Articles 2850 @using Dynamicweb.Rapido.Blocks 2851 2852 @* Component for the articles *@ 2853 2854 @helper RenderArticleGalleryModal(ArticleGalleryModal settings) 2855 { 2856 Modal galleryModal = new Modal 2857 { 2858 Id = "ParagraphGallery", 2859 Width = ModalWidth.Full, 2860 BodyTemplate = RenderArticleGalleryModalContent() 2861 }; 2862 2863 @Render(galleryModal) 2864 } 2865 2866 @helper RenderArticleGalleryModalContent() { 2867 <div class="modal__image-min-size-wrapper"> 2868 @Render(new Image { 2869 Id = "ParagraphGallery", 2870 Path = "#", 2871 CssClass = "modal--full__img", 2872 DisableLazyLoad = true, 2873 DisableImageEngine = true 2874 }) 2875 </div> 2876 2877 <div class="modal__images-counter" id="ParagraphGallery_counter"></div> 2878 2879 @Render(new Button { 2880 Id = "ParagraphGallery_prev", 2881 ButtonType = ButtonType.Button, 2882 ButtonLayout = ButtonLayout.None, 2883 CssClass = "modal__prev-btn", 2884 Icon = new Icon { Prefix = "far", Name = "fa-angle-left", LabelPosition = IconLabelPosition.After }, 2885 OnClick = "Gallery.prevImage('ParagraphGallery')" 2886 }) 2887 2888 @Render(new Button { 2889 Id = "ParagraphGallery_next", 2890 ButtonType = ButtonType.Button, 2891 ButtonLayout = ButtonLayout.None, 2892 CssClass = "modal__next-btn", 2893 Icon = new Icon { Prefix = "far", Name = "fa-angle-right", LabelPosition = IconLabelPosition.After }, 2894 OnClick = "Gallery.nextImage('ParagraphGallery')" 2895 }) 2896 } 2897 @using System.Reflection 2898 @using Dynamicweb.Rapido.Blocks.Components 2899 @using Dynamicweb.Rapido.Blocks.Components.Articles 2900 @using Dynamicweb.Rapido.Blocks 2901 2902 2903 @* Component for the articles *@ 2904 2905 @helper RenderArticleRelated(ArticleRelated settings) 2906 { 2907 string cardClass = Pageview.Device.ToString() != "Tablet" ? "card u-color-light--bg u-full-height" : ""; 2908 string cardFooterClass = Pageview.Device.ToString() != "Tablet" ? "card-footer u-color-light--bg" : ""; 2909 2910 <section class="multiple-paragraphs-container u-color-light-gray--bg paragraph-container--full-width"> 2911 <div class="center-container dw-mod"> 2912 <div class="grid u-padding"> 2913 <div class="grid__col-md-12 grid__col-xs-12"> 2914 <h2 class="article__header u-no-margin u-margin-top">@settings.Title</h2> 2915 </div> 2916 </div> 2917 2918 <div class="js-handlebars-root u-padding" id="@settings.Title.Replace(" ", String.Empty)" data-template="RelatedSimpleTemplate" data-json-feed="/Default.aspx?ID=@settings.FeedPageId&@settings.Query&ExcludeItemID=@settings.CurrentPageId&PageSize=@settings.PageSize"></div> 2919 2920 <script id="RelatedSimpleTemplate" type="text/x-template"> 2921 {{#.}} 2922 <div class="grid u-padding-bottom--lg"> 2923 {{#Cases}} 2924 <div class="grid__col-lg-3 grid__col-sm-6 image-hover--zoom dw-mod"> 2925 <a href="{{link}}" class="u-full-height u-color-light--bg"> 2926 {{#if image}} 2927 <div class="u-color-light--bg u-no-padding dw-mod"> 2928 <div class="flex-img image-hover__wrapper"> 2929 <img class="b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=680&height=314&amp;crop=1&amp;DoNotUpscale=True&amp;Compression=75&amp;image={{image}}" alt="{{title}}" /> 2930 </div> 2931 </div> 2932 {{/if}} 2933 2934 <div class="card u-color-light--bg dw-mod"> 2935 <h3 class="article-list__item-header u-truncate-text dw-mod">{{title}}</h3> 2936 <p class="article__short-summary dw-mod">{{summary}}</p> 2937 </div> 2938 </a> 2939 </div> 2940 {{/Cases}} 2941 </div> 2942 {{/.}} 2943 </script> 2944 </div> 2945 </section> 2946 } 2947 @using System.Reflection 2948 @using Dynamicweb.Rapido.Blocks.Components 2949 @using Dynamicweb.Rapido.Blocks.Components.Articles 2950 @using Dynamicweb.Rapido.Blocks 2951 2952 2953 @* Component for the articles *@ 2954 2955 @helper RenderArticleMenu(ArticleMenu settings) 2956 { 2957 if (!String.IsNullOrEmpty(settings.Title)) { 2958 <div class="u-margin u-border-bottom"> 2959 <h3 class="u-no-margin">@settings.Title</h3> 2960 </div> 2961 } 2962 2963 <ul class="menu-left u-margin-bottom dw-mod"> 2964 @foreach (var item in settings.Items) 2965 { 2966 @Render(item) 2967 } 2968 </ul> 2969 } 2970 2971 @helper RenderArticleMenuItem(ArticleMenuItem settings) 2972 { 2973 string link = !String.IsNullOrEmpty(settings.Link) ? settings.Link : "#"; 2974 2975 if (!String.IsNullOrEmpty(settings.Title)) { 2976 <li class="menu-left__item dw-mod"> 2977 <a href="@link" onclick="@settings.OnClick" class="menu-left__link dw-mod">@settings.Title</a> 2978 </li> 2979 } 2980 } 2981 @using System.Reflection 2982 @using Dynamicweb.Rapido.Blocks.Components 2983 @using Dynamicweb.Rapido.Blocks.Components.Articles 2984 @using Dynamicweb.Rapido.Blocks 2985 2986 @* Component for the articles *@ 2987 2988 @helper RenderArticleList(ArticleList settings) 2989 { 2990 if (Pageview != null) 2991 { 2992 bool isParagraph = Pageview.CurrentParagraph != null ? true : false; 2993 string[] sortArticlesListBy = new string[2]; 2994 2995 if (isParagraph) { 2996 sortArticlesListBy = Pageview.CurrentParagraph.Item["SortArticlesListBy"] != null && !string.IsNullOrEmpty(Pageview.CurrentParagraph.Item["SortArticlesListBy"].ToString()) ? Pageview.CurrentParagraph.Item["SortArticlesListBy"].ToString().Split('+') : new string[] { "Date", "ASC" }; 2997 } 2998 else { 2999 sortArticlesListBy = Pageview.Item["SortArticlesListBy"] != null && !string.IsNullOrEmpty(Pageview.Item["SortArticlesListBy"].ToString()) ? Pageview.Item["SortArticlesListBy"].ToString().Split('+') : new string[] { "Date", "ASC" }; 3000 } 3001 3002 string sourcePage = settings.SourcePage != null ? settings.SourcePage : Pageview.ID.ToString(); 3003 3004 if (!settings.DisablePagination) { 3005 @RenderItemList(new 3006 { 3007 ItemType = !String.IsNullOrEmpty(settings.ItemType) ? settings.ItemType : "DynamicArticle", 3008 ListSourceType = settings.SourceType, 3009 ListSourcePage = sourcePage, 3010 ItemFieldsList = "*", 3011 Filter = settings.Filter, 3012 ListOrderBy = sortArticlesListBy[0], 3013 ListOrderByDirection = sortArticlesListBy[1], 3014 ListSecondOrderBy = sortArticlesListBy[0] == "Date" ? "InFocusSortId" : "Date", 3015 ListSecondOrderByDirection = "ASC", 3016 IncludeAllChildItems = true, 3017 ListTemplate = settings.Template, 3018 ListPageSize = settings.PageSize.ToString() 3019 }); 3020 } else { 3021 @RenderItemList(new 3022 { 3023 ItemType = !String.IsNullOrEmpty(settings.ItemType) ? settings.ItemType : "DynamicArticle", 3024 ListSourceType = settings.SourceType, 3025 ListSourcePage = sourcePage, 3026 ItemFieldsList = "*", 3027 Filter = settings.Filter, 3028 ListOrderBy = sortArticlesListBy[0], 3029 ListOrderByDirection = sortArticlesListBy[1], 3030 ListSecondOrderBy = sortArticlesListBy[0] == "Date" ? "InFocusSortId" : "Date", 3031 ListSecondOrderByDirection = "ASC", 3032 IncludeAllChildItems = true, 3033 ListTemplate = settings.Template, 3034 ListPageSize = settings.PageSize.ToString(), 3035 ListViewMode = "Partial", 3036 ListShowTo = settings.PageSize + 1 3037 }); 3038 } 3039 } 3040 } 3041 @using System.Reflection 3042 @using Dynamicweb.Rapido.Blocks.Components.Articles 3043 3044 3045 @* Component for the articles *@ 3046 3047 @helper RenderArticleSummary(ArticleSummary settings) 3048 { 3049 if (!String.IsNullOrEmpty(settings.Text)) 3050 { 3051 <div class="article__summary dw-mod">@settings.Text</div> 3052 } 3053 } 3054 @using System.Reflection 3055 @using Dynamicweb.Rapido.Blocks.Components 3056 @using Dynamicweb.Rapido.Blocks.Components.Articles 3057 @using Dynamicweb.Rapido.Blocks 3058 3059 @* Component for the articles *@ 3060 3061 @helper RenderArticleListCategoryFilter(ArticleListCategoryFilter settings) 3062 { 3063 string pageId = Pageview.ID.ToString(); 3064 string selectedFilter = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("sourcePage")) ? HttpContext.Current.Request.QueryString.Get("sourcePage") : Translate("All"); 3065 var query = HttpUtility.ParseQueryString(HttpContext.Current.Request.QueryString.ToString()); 3066 3067 foreach (var option in settings.Categories) 3068 { 3069 selectedFilter = selectedFilter == option.Value ? option.Key : selectedFilter; 3070 } 3071 3072 if (selectedFilter == pageId) 3073 { 3074 selectedFilter = Translate("All"); 3075 } 3076 3077 if (Pageview.Device.ToString() != "Mobile" && Pageview.Device.ToString() != "Tablet") 3078 { 3079 <div class="u-pull--right u-margin-left"> 3080 <div class="collection u-no-margin"> 3081 <h5>@Translate("Category")</h5> 3082 <input type="checkbox" id="CategorySelector" class="dropdown-trigger" /> 3083 <div class="dropdown u-w180px dw-mod"> 3084 <label class="dropdown__header dropdown__btn dw-mod" for="CategorySelector">@Translate(selectedFilter)</label> 3085 <div class="dropdown__content dw-mod"> 3086 @foreach (var option in settings.Categories) 3087 { 3088 <div class="dropdown__item" onclick="QueryArray.setParametersInCurrentURL({ sourceType: 'Page', sourcePage: '@(option.Key.ToLower() == "all" ? pageId : option.Value)' })">@Translate(option.Key)</div> 3089 } 3090 </div> 3091 <label class="dropdown-trigger-off" for="CategorySelector"></label> 3092 </div> 3093 </div> 3094 </div> 3095 } 3096 else 3097 { 3098 <div class="u-full-width u-margin-bottom"> 3099 <h5 class="u-no-margin">@Translate("Category")</h5> 3100 <input type="checkbox" id="CategorySelector" class="dropdown-trigger" /> 3101 <div class="dropdown u-full-width dw-mod"> 3102 <label class="dropdown__header dropdown__btn dw-mod" for="CategorySelector">@Translate(selectedFilter)</label> 3103 <div class="dropdown__content dw-mod"> 3104 @foreach (var option in settings.Categories) 3105 { 3106 <div class="dropdown__item" onclick="QueryArray.setParametersInCurrentURL({ sourceType: 'Page', sourcePage: '@(option.Key.ToLower() == "all" ? pageId : option.Value)' })">@Translate(option.Key)</div> 3107 } 3108 </div> 3109 <label class="dropdown-trigger-off" for="CategorySelector"></label> 3110 </div> 3111 </div> 3112 } 3113 } 3114 @using System.Reflection 3115 @using Dynamicweb.Rapido.Blocks.Components 3116 @using Dynamicweb.Rapido.Blocks.Components.Articles 3117 @using Dynamicweb.Rapido.Blocks 3118 @using System.Collections.Generic 3119 3120 @* Component for the articles *@ 3121 3122 @helper RenderArticleListFilter(ArticleListFilter settings) 3123 { 3124 string selectedFilter = !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get(settings.SystemName)) ? HttpContext.Current.Request.QueryString.Get(settings.SystemName) : Translate("All"); 3125 var query = HttpUtility.ParseQueryString(HttpContext.Current.Request.QueryString.ToString()); 3126 3127 if (settings.Options != null) 3128 { 3129 if (settings.Options is IEnumerable<dynamic>) 3130 { 3131 var options = (IEnumerable<dynamic>) settings.Options; 3132 settings.Options = options.OrderBy(item => item.Name); 3133 } 3134 3135 foreach (var option in settings.Options) 3136 { 3137 selectedFilter = selectedFilter == option.Value ? option.Name : selectedFilter; 3138 } 3139 3140 if (Pageview.Device.ToString() != "Mobile" && Pageview.Device.ToString() != "Tablet") 3141 { 3142 <div class="u-pull--right u-margin-left"> 3143 <div class="collection u-no-margin"> 3144 <h5>@settings.Label</h5> 3145 <input type="checkbox" id="@(settings.SystemName)Selector" class="dropdown-trigger" /> 3146 <div class="dropdown u-w180px dw-mod"> 3147 <label class="dropdown__header dropdown__btn dw-mod" for="@(settings.SystemName)Selector">@Translate(selectedFilter)</label> 3148 <div class="dropdown__content dw-mod"> 3149 <div class="dropdown__item" onclick="QueryArray.setParameterInCurrentURL('@settings.SystemName', '')">@Translate("All")</div> 3150 @foreach (var option in settings.Options) 3151 { 3152 <div class="dropdown__item" onclick="QueryArray.setParameterInCurrentURL('@settings.SystemName', '@option.Value')">@Translate(option.Name)</div> 3153 } 3154 </div> 3155 <label class="dropdown-trigger-off" for="@(settings.SystemName)Selector"></label> 3156 </div> 3157 </div> 3158 </div> 3159 } 3160 else 3161 { 3162 <div class="u-full-width u-margin-bottom"> 3163 <h5 class="u-no-margin">@settings.Label</h5> 3164 <input type="checkbox" id="@(settings.SystemName)Selector" class="dropdown-trigger" /> 3165 <div class="dropdown u-full-width w-mod"> 3166 <label class="dropdown__header dropdown__btn dw-mod" for="@(settings.SystemName)Selector">@Translate(selectedFilter)</label> 3167 <div class="dropdown__content dw-mod"> 3168 <div class="dropdown__item" onclick="QueryArray.setParameterInCurrentURL('@settings.SystemName', '')">@Translate("All")</div> 3169 @foreach (var option in settings.Options) 3170 { 3171 <div class="dropdown__item" onclick="QueryArray.setParameterInCurrentURL('@settings.SystemName', '@option.Value')">@Translate(option.Name)</div> 3172 } 3173 </div> 3174 <label class="dropdown-trigger-off" for="@(settings.SystemName)Selector"></label> 3175 </div> 3176 </div> 3177 } 3178 } 3179 } 3180 @using System.Reflection 3181 @using Dynamicweb.Rapido.Blocks.Components 3182 @using Dynamicweb.Rapido.Blocks.Components.Articles 3183 @using Dynamicweb.Rapido.Blocks 3184 3185 @* Component for the articles *@ 3186 3187 @helper RenderArticleListSearch(ArticleListSearch settings) 3188 { 3189 string searchParameter = !string.IsNullOrEmpty(settings.SearchParameter) ? settings.SearchParameter : "Title"; 3190 string searchWord = HttpContext.Current.Request.QueryString.Get(searchParameter); 3191 string searchString = !string.IsNullOrEmpty(searchWord) ? searchWord.Trim('*') : ""; 3192 string className = "u-w340px u-pull--right u-margin-left"; 3193 3194 if (Pageview.Device.ToString() == "Mobile" || Pageview.Device.ToString() == "Tablet") 3195 { 3196 className = "u-full-width"; 3197 } 3198 3199 <div class="typeahead u-color-inherit u-margin-bottom dw-mod @className"> 3200 <input type="text" class="typeahead-search-field u-no-margin dw-mod" placeholder="@Translate("Search in list")" value="@searchString" id="ArticleListSearchInput" onchange="QueryArray.setParameterInCurrentURL('@searchParameter', '*' + document.getElementById('ArticleListSearchInput').value + '*')"> 3201 <button type="button" class="btn btn--condensed btn--primary u-no-margin dw-mod"><i class="fas fa-search"></i></button> 3202 </div> 3203 } 3204 @using System.Reflection 3205 @using Dynamicweb.Rapido.Blocks.Components 3206 @using Dynamicweb.Rapido.Blocks.Components.Articles 3207 @using Dynamicweb.Rapido.Blocks 3208 3209 @* Component for the articles *@ 3210 3211 @helper RenderArticleListNoResultsInfo(ArticleListNoResultsInfo settings) 3212 { 3213 <div class="u-margin-top--lg u-bold u-ta-center u-bold">@Translate(settings.Message)</div> 3214 } 3215 @using System.Reflection 3216 @using Dynamicweb.Rapido.Blocks.Components 3217 @using Dynamicweb.Rapido.Blocks.Components.General 3218 @using Dynamicweb.Rapido.Blocks.Components.Articles 3219 @using Dynamicweb.Rapido.Blocks 3220 @using System.Text.RegularExpressions 3221 3222 @* Component for the articles *@ 3223 3224 @helper RenderArticleListItem(ArticleListItem settings) 3225 { 3226 switch (settings.Type) { 3227 case ArticleListItemType.Card: 3228 @RenderArticleListItemCard(settings); 3229 break; 3230 case ArticleListItemType.List: 3231 @RenderArticleListItemList(settings); 3232 break; 3233 case ArticleListItemType.Simple: 3234 @RenderArticleListItemSimple(settings); 3235 break; 3236 default: 3237 @RenderArticleListItemCard(settings); 3238 break; 3239 } 3240 } 3241 3242 @helper RenderArticleListItemCard(ArticleListItem settings) { 3243 <a href="@settings.Link" class="u-full-height u-color-light--bg"> 3244 <div class="u-color-light--bg u-no-padding dw-mod"> 3245 @if (settings.Logo != null) 3246 { 3247 string backgroundImage = settings.Image != null ? "background-image:url(/Admin/Public/GetImage.ashx?width=992&amp;height=760&amp;crop=0&amp;Compression=75&amp;DoNotUpscale=True&amp;image=" + settings.Image.Path + "); background-size: cover;" : ""; 3248 settings.Logo.ImageDefault.Crop = 5; 3249 settings.Logo.ImageDefault.Width = settings.Logo.ImageDefault.Width == 1920 ? 240 : settings.Logo.ImageDefault.Width; 3250 settings.Logo.ImageDefault.Height = settings.Logo.ImageDefault.Height == 1080 ? 200 : settings.Logo.ImageDefault.Height; 3251 <div class="image-hover__wrapper layered-image layered-image--tinted dw-mod" style="@backgroundImage"> 3252 @if (settings.Stickers != null) 3253 { 3254 if (settings.Stickers.Position != StickersListPosition.Custom) 3255 { 3256 @Render(settings.Stickers); 3257 } 3258 } 3259 @RenderImage(settings.Logo) 3260 </div> 3261 } else if (settings.Image != null) 3262 { 3263 <div class="flex-img image-hover__wrapper u-position-relative dw-mod"> 3264 @if (settings.Stickers != null) 3265 { 3266 if (settings.Stickers.Position != StickersListPosition.Custom) 3267 { 3268 @Render(settings.Stickers); 3269 } 3270 } 3271 @Render(settings.Image) 3272 </div> 3273 } 3274 </div> 3275 3276 @if (!String.IsNullOrEmpty(settings.Title) || !String.IsNullOrEmpty(settings.Summary)) 3277 { 3278 <div class="card u-color-light--bg dw-mod"> 3279 @if (settings.Stickers != null) 3280 { 3281 if (settings.Stickers.Position == StickersListPosition.Custom) 3282 { 3283 @Render(settings.Stickers); 3284 } 3285 } 3286 @if (!String.IsNullOrEmpty(settings.Title)) 3287 { 3288 <h3 class="article-list__item-header u-truncate-text dw-mod">@settings.Title</h3> 3289 } 3290 @if (!String.IsNullOrEmpty(settings.SubTitle)) 3291 { 3292 <div class="article-list__item-micro-info u-truncate-text dw-mod">@settings.SubTitle</div> 3293 } 3294 @if (!String.IsNullOrEmpty(settings.Summary)) 3295 { 3296 <p class="article__short-summary dw-mod">@settings.Summary</p> 3297 } 3298 </div> 3299 } 3300 </a> 3301 } 3302 3303 @helper RenderArticleListItemList(ArticleListItem settings) { 3304 <a href="@settings.Link"> 3305 <div class="grid u-color-light--bg u-no-padding dw-mod"> 3306 <div class="grid__col-md-3"> 3307 <div class="u-color-light--bg u-no-padding dw-mod"> 3308 @if (settings.Logo != null) 3309 { 3310 string backgroundImage = settings.Image != null ? "background-image:url(/Admin/Public/GetImage.ashx?width=992&amp;height=760&amp;crop=0&amp;Compression=75&amp;DoNotUpscale=True&amp;image=" + settings.Image.Path + "); background-size: cover;" : ""; 3311 settings.Logo.ImageDefault.Crop = 5; 3312 settings.Logo.ImageDefault.Width = settings.Logo.ImageDefault.Width == 1920 ? 240 : settings.Logo.ImageDefault.Width; 3313 settings.Logo.ImageDefault.Height = settings.Logo.ImageDefault.Height == 1080 ? 200 : settings.Logo.ImageDefault.Height; 3314 <div class="image-hover__wrapper layered-image layered-image--tinted dw-mod" style="@backgroundImage"> 3315 @if (settings.Stickers != null) 3316 { 3317 if (settings.Stickers.Position != StickersListPosition.Custom) 3318 { 3319 @Render(settings.Stickers); 3320 } 3321 } 3322 @RenderImage(settings.Logo) 3323 </div> 3324 } else if (settings.Image != null) 3325 { 3326 <div class="flex-img image-hover__wrapper dw-mod"> 3327 @if (settings.Stickers != null) 3328 { 3329 if (settings.Stickers.Position != StickersListPosition.Custom) 3330 { 3331 @Render(settings.Stickers); 3332 } 3333 } 3334 @Render(settings.Image) 3335 </div> 3336 } 3337 </div> 3338 </div> 3339 3340 @if (!String.IsNullOrEmpty(settings.Title) || !String.IsNullOrEmpty(settings.Summary)) 3341 { 3342 <div class="grid__col-md-9"> 3343 @if (!String.IsNullOrEmpty(settings.Title)) 3344 { 3345 <h3 class="article-list__item-header u-truncate-text dw-mod">@settings.Title</h3> 3346 } 3347 @if (settings.Stickers != null) 3348 { 3349 if (settings.Stickers.Position == StickersListPosition.Custom) 3350 { 3351 @Render(settings.Stickers); 3352 } 3353 } 3354 @if (!String.IsNullOrEmpty(settings.SubTitle)) 3355 { 3356 <div class="article-list__item-micro-info u-truncate-text dw-mod">@settings.SubTitle</div> 3357 } 3358 @if (!String.IsNullOrEmpty(settings.Summary)) 3359 { 3360 <p class="article__short-summary dw-mod">@settings.Summary</p> 3361 } 3362 </div> 3363 } 3364 </div> 3365 </a> 3366 } 3367 3368 @helper RenderArticleListItemSimple(ArticleListItem settings) { 3369 <a href="@settings.Link" class="u-color-inherit"> 3370 <div class="grid u-color-light--bg u-no-padding dw-mod"> 3371 <div class="grid__col-md-12"> 3372 @if (!String.IsNullOrEmpty(settings.Title)) 3373 { 3374 <div class="article-list-item__header u-truncate-text u-no-margin dw-mod">@settings.Title</div> 3375 } 3376 @if (!String.IsNullOrEmpty(settings.SubTitle)) 3377 { 3378 <div class="article-list__item-micro-info u-truncate-text dw-mod">@settings.SubTitle</div> 3379 } 3380 </div> 3381 </div> 3382 </a> 3383 } 3384 @using System.Reflection 3385 @using Dynamicweb.Rapido.Blocks.Components.Articles 3386 3387 3388 @* Component for the articles *@ 3389 3390 @helper RenderArticleAuthorAndDate(ArticleAuthorAndDate settings) 3391 { 3392 <small class="article__subscription"> 3393 @if (!(string.IsNullOrWhiteSpace(settings.Author) && string.IsNullOrWhiteSpace(settings.Date))) 3394 { 3395 <text>@Translate("Written")</text> 3396 } 3397 @if (!string.IsNullOrWhiteSpace(settings.Author)) 3398 { 3399 <text>@Translate("by") @settings.Author</text> 3400 } 3401 @if (!string.IsNullOrWhiteSpace(settings.Date)) 3402 { 3403 <text>@Translate("on") @settings.Date</text> 3404 } 3405 </small> 3406 } 3407 @using System.Reflection 3408 @using Dynamicweb.Rapido.Blocks.Components.Articles 3409 @using Dynamicweb.Rapido.Blocks.Components.General 3410 3411 3412 @* Component for the articles *@ 3413 3414 @helper RenderArticleLink(ArticleLink settings) 3415 { 3416 if (!string.IsNullOrEmpty(settings.Title)) 3417 { 3418 Button link = new Button { 3419 ConfirmText = settings.ConfirmText, 3420 ConfirmTitle = settings.ConfirmTitle, 3421 ButtonType = settings.ButtonType, 3422 Id = settings.Id, 3423 Title = settings.Title, 3424 AltText = settings.AltText, 3425 OnClick = settings.OnClick, 3426 CssClass = settings.CssClass, 3427 Disabled = settings.Disabled, 3428 Icon = settings.Icon, 3429 Name = settings.Name, 3430 Href = settings.Href, 3431 ButtonLayout = settings.ButtonLayout, 3432 ExtraAttributes = settings.ExtraAttributes 3433 }; 3434 <div class="grid__cell"> 3435 @Render(link) 3436 </div> 3437 } 3438 } 3439 @using System.Reflection 3440 @using Dynamicweb.Rapido.Blocks 3441 @using Dynamicweb.Rapido.Blocks.Components.Articles 3442 @using Dynamicweb.Rapido.Blocks.Components.General 3443 3444 3445 @* Component for the articles *@ 3446 3447 @helper RenderArticleCarousel(ArticleCarousel settings) 3448 { 3449 <div class="grid"> 3450 <div class="grid__col-12"> 3451 <div class="carousel" id="carousel_@settings.Id"> 3452 <div class="carousel__container js-carousel-slides dw-mod"> 3453 @RenderBlockList(settings.SubBlocks) 3454 </div> 3455 </div> 3456 </div> 3457 </div> 3458 3459 <script> 3460 document.addEventListener("DOMContentLoaded", function () { 3461 new CarouselModule("#carousel_@settings.Id", { 3462 slideTime: 0, 3463 dots: true 3464 }); 3465 }); 3466 </script> 3467 } 3468 3469 @helper RenderArticleCarouselSlide(ArticleCarouselSlide settings) 3470 { 3471 string imageEngine = "/Admin/Public/GetImage.ashx?"; 3472 3473 string defaultImage = settings.ImageSettings != null ? imageEngine : settings.Image; 3474 if (settings.ImageSettings != null) 3475 { 3476 defaultImage += settings.ImageSettings.Width != 0 ? "Width=" + settings.ImageSettings.Width + "&" : ""; 3477 defaultImage += settings.ImageSettings.Height != 0 ? "Height=" + settings.ImageSettings.Height + "&" : ""; 3478 defaultImage += "Crop=" + settings.ImageSettings.Crop + "&"; 3479 defaultImage += "Compression=" + settings.ImageSettings.Compression + "&"; 3480 defaultImage += "DoNotUpscale=" + settings.ImageSettings.DoNotUpscale.ToString() + "&"; 3481 defaultImage += "FillCanvas=" + settings.ImageSettings.FillCanvas.ToString() + "&"; 3482 defaultImage += "format=webp&"; 3483 } 3484 defaultImage += "&Image=" + settings.Image; 3485 3486 <div class="custom-carousel__slide u-min-h300px u-flex dw-mod" style="background-size:cover; background-image:url('@defaultImage')"> 3487 <a class="article-carousel-item__wrap" href="@settings.Link" title="@settings.Title"> 3488 <h2 class="article-list__item-header u-truncate-text u-color-light dw-mod">@settings.Title</h2> 3489 <div class="article-list__item-info"> 3490 @if (settings.Stickers != null) 3491 { 3492 settings.Stickers.Position = StickersListPosition.Custom; 3493 @Render(settings.Stickers); 3494 } 3495 3496 <small class="u-margin-top--lg u-color-light"> 3497 @if (!(string.IsNullOrWhiteSpace(settings.Author) && string.IsNullOrWhiteSpace(settings.Date))) 3498 { 3499 <text>@Translate("Written")</text> 3500 } 3501 @if (!string.IsNullOrWhiteSpace(settings.Author)) 3502 { 3503 <text>@Translate("by") @settings.Author</text> 3504 } 3505 @if (!string.IsNullOrWhiteSpace(settings.Date)) 3506 { 3507 <text>@Translate("on") @settings.Date</text> 3508 } 3509 </small> 3510 </div> 3511 3512 <h3 class="article__short-summary u-color-light">@settings.Summary</h3> 3513 </a> 3514 @if (settings.UseFilters == true) 3515 { 3516 <div class="background-image image-filter image-filter--darken dw-mod"></div> 3517 } 3518 </div> 3519 } 3520 @using System.Text.RegularExpressions 3521 @using Dynamicweb.Rapido.Blocks.Components 3522 @using Dynamicweb.Rapido.Blocks.Components.General 3523 @using Dynamicweb.Rapido.Blocks.Components.Articles 3524 @using Dynamicweb.Rapido.Blocks 3525 3526 @* Component for the articles *@ 3527 3528 @helper RenderArticleVideo(ArticleVideo settings) 3529 { 3530 if (settings.Url != null) 3531 { 3532 //getting video ID from youtube URL 3533 string videoCode = settings.Url; 3534 Regex regex = new Regex(@".be\/(.[^?]*)"); 3535 Match match = regex.Match(videoCode); 3536 string videoId = ""; 3537 if (match.Success) 3538 { 3539 videoId = match.Groups[1].Value; 3540 } 3541 else 3542 { 3543 regex = new Regex(@"v=([^&]+)"); 3544 match = regex.Match(videoCode); 3545 if (match.Success) 3546 { 3547 videoId = match.Groups[1].Value; 3548 } 3549 } 3550 3551 int autoPlay = settings.AutoPlay == "true" ? 1 : 0; 3552 3553 <div class="video-wrapper"> 3554 <div class="js-youtube-video" data-video="@videoId" id="ytPlayer@(Guid.NewGuid().ToString("N"))" data-auto-play="@autoPlay" data-enable-controls="1"></div> 3555 </div> 3556 } 3557 } 3558 3559 3560 3561 @* Simple helpers *@ 3562 3563 @*Requires the Gallery ItemType that comes with Rapido*@ 3564 @helper RenderArticleItemGallery(IList<ItemViewModel> gallery) { 3565 if (gallery != null && gallery.Count > 0) 3566 { 3567 int count = 1; 3568 3569 foreach (var item in gallery) 3570 { 3571 if (item.GetFile("ImagePath") != null) 3572 { 3573 string image = item.GetFile("ImagePath").PathUrlEncoded; 3574 string imagePrefix = "/Admin/Public/GetImage.ashx?width=1200&amp;height=820&amp;crop=5&amp;Compression=75&amp;DoNotUpscale=1&amp;image="; 3575 int imagesCount = gallery.Count; 3576 3577 if (count == 1) 3578 { 3579 <label class="gallery" for="ParagraphGalleryModalTrigger" onclick="Gallery.openImage(this.querySelector('.js-gallery'))"> 3580 <span class="gallery__main-image"> 3581 <img src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=992&amp;height=760&amp;crop=0&amp;Compression=75&amp;DoNotUpscale=1&amp;image=@image" class="b-lazy flex-img js-gallery" alt="" data-for="ParagraphGallery" data-image="@imagePrefix@image" /> 3582 </span> 3583 <span class="gallery__image-counter"> 3584 <i class="fas fa-camera fa-2x"></i> <span class="gallery__image-counter__number">@imagesCount</span> 3585 <span class="gallery__image-counter__text">@Translate("See all") <i class="fas fa-angle-right"></i></span> 3586 </span> 3587 </label> 3588 } 3589 else 3590 { 3591 <div class="u-hidden js-gallery" data-for="ParagraphGallery" data-image="@imagePrefix@image"></div> 3592 } 3593 3594 count++; 3595 } 3596 } 3597 3598 @Render(new ArticleGalleryModal()) 3599 } 3600 } 3601 3602 @helper RenderMobileFilters(List<Block> subBlocks) 3603 { 3604 if (subBlocks.Count > 0) 3605 { 3606 <div class="grid__col-12"> 3607 <input type="checkbox" id="CheckFilters" class="js-remember-state u-hidden" data-expand="CheckFilters" /> 3608 <div class="grid u-margin-bottom dw-mod" data-trigger="CheckFilters"> 3609 @RenderBlockList(subBlocks) 3610 </div> 3611 <label for="CheckFilters" class="btn btn--secondary btn--full dw-mod js-expand-hide" data-trigger="CheckFilters">@Translate("Select filters")</label> 3612 <label for="CheckFilters" class="btn btn--secondary btn--full dw-mod expandable--collapsed" data-trigger="CheckFilters">@Translate("Close filters")</label> 3613 </div> 3614 } 3615 } 3616 3617 3618 @* Include the Blocks for the page *@ 3619 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 3620 3621 @using System 3622 @using System.Web 3623 @using System.Collections.Generic 3624 @using Dynamicweb.Environment 3625 @using Dynamicweb.Rapido.Blocks.Extensibility 3626 @using Dynamicweb.Rapido.Blocks 3627 @using Dynamicweb.Core 3628 @using Dynamicweb.Frontend 3629 @using Dynamicweb.Configuration 3630 @using Custom.PhilipsonWine.Security.Helpers 3631 3632 @functions { 3633 string GoogleTagManagerID = ""; 3634 string GoogleAnalyticsID = ""; 3635 3636 public string GetCustomUserFieldValue(string fieldName) 3637 { 3638 var currentUser = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser(); 3639 if (currentUser != null) 3640 { 3641 return Converter.ToString(currentUser.CustomFieldValues.FirstOrDefault(x => x.CustomField.SystemName == fieldName)?.Value); 3642 } 3643 3644 return ""; 3645 } 3646 } 3647 3648 @{ 3649 GoogleTagManagerID = Model.Area.Item.GetItem("Settings").GetString("GoogleTagManagerID"); 3650 GoogleAnalyticsID = Model.Area.Item.GetItem("Settings").GetString("GoogleAnalyticsTrackingID"); 3651 string trustpilotFreeWidget = Model.Area.Item.GetItem("Custom").GetString("FooterTrustpilotFreeWidget"); 3652 3653 BlocksPage topSnippetsBlocksPage = BlocksPage.GetBlockPage("Master"); 3654 3655 3656 Block cookieInformation = new Block() 3657 { 3658 Id = "CookieInformation", 3659 SortId = 25, 3660 Template = RenderCookieInformation() 3661 }; 3662 topSnippetsBlocksPage.Add("Head", cookieInformation); 3663 3664 Block googleConsentModeBlock = new Block() 3665 { 3666 Id = "GoogleConsentMode", 3667 // MUST be rendered before GA 3668 SortId = 9, 3669 Template = RenderGoogleConsentMode() 3670 }; 3671 topSnippetsBlocksPage.Add("Head", googleConsentModeBlock); 3672 3673 if (!string.IsNullOrWhiteSpace(GoogleAnalyticsID)) 3674 { 3675 Block tagManager = new Block() 3676 { 3677 Id = "GoogleAnalytics", 3678 SortId = 10, 3679 Template = RenderGoogleAnalyticsSnippet() 3680 }; 3681 topSnippetsBlocksPage.Add("Head", tagManager); 3682 } 3683 3684 if (!string.IsNullOrWhiteSpace(GoogleTagManagerID)) 3685 { 3686 Block GTMDataLayer = new Block() 3687 { 3688 Id = "GTMDataLayer", 3689 SortId = 0, 3690 Template = RenderGTMDataLayer() 3691 }; 3692 topSnippetsBlocksPage.Add("Head", GTMDataLayer); 3693 3694 Block dataLayerHelpers = new Block() 3695 { 3696 Id = "DataLayerHelpers", 3697 SortId = 1, 3698 Template = RenderDataLayerHelpers() 3699 }; 3700 topSnippetsBlocksPage.Add("Head", dataLayerHelpers); 3701 3702 Block tagManager = new Block() 3703 { 3704 Id = "TagManager", 3705 SortId = 20, 3706 Template = RenderGoogleTagManager() 3707 }; 3708 topSnippetsBlocksPage.Add("Head", tagManager); 3709 3710 Block tagManagerBodySnippet = new Block() 3711 { 3712 Id = "TagManagerBodySnippet", 3713 SortId = 20, 3714 Template = RenderGoogleTagManagerBodySnippet() 3715 }; 3716 topSnippetsBlocksPage.Add(MasterBlockId.MasterTopSnippets, tagManagerBodySnippet); 3717 } 3718 3719 Block facebookPixel = new Block() 3720 { 3721 Id = "FacebookPixel", 3722 SortId = 30, 3723 Template = RenderFacebookPixel() 3724 }; 3725 3726 topSnippetsBlocksPage.Add(MasterBlockId.MasterTopSnippets, facebookPixel); 3727 3728 Block facebookPixelProductPage = new Block() 3729 { 3730 Id = "FacebookPixelProductPage", 3731 SortId = 31, 3732 Template = RenderFacebookPixelProductPage() 3733 }; 3734 3735 topSnippetsBlocksPage.Add(MasterBlockId.MasterTopSnippets, facebookPixelProductPage); 3736 3737 Block oneSignalBlock = new Block() 3738 { 3739 Id = "OneSignal", 3740 SortId = 50, 3741 Template = RenderOneSignalScript() 3742 }; 3743 3744 topSnippetsBlocksPage.Add("Head", oneSignalBlock); 3745 3746 Block openSearchBlock = new Block() 3747 { 3748 Id = "OpenSearch", 3749 SortId = 50, 3750 Template = RenderOpenSearchReference() 3751 }; 3752 3753 topSnippetsBlocksPage.Add("Head", openSearchBlock); 3754 3755 if (!string.IsNullOrEmpty(trustpilotFreeWidget)) 3756 { 3757 Block trustpilotScriptBlock = new Block() 3758 { 3759 Id = "TrustpilotScript", 3760 SortId = 70, 3761 Template = TrustpilotScript() 3762 }; 3763 3764 topSnippetsBlocksPage.Add("Head", trustpilotScriptBlock); 3765 } 3766 3767 string simplifyId = PageView.Current().AreaSettings.GetItem("Custom").GetString("SimplifyId"); 3768 3769 if (!string.IsNullOrEmpty(simplifyId)) 3770 { 3771 Block simplifyScriptBlock = new Block() 3772 { 3773 Id = "SimplifyScript", 3774 SortId = 5, 3775 Template = RenderSimplifyScript(simplifyId) 3776 }; 3777 3778 topSnippetsBlocksPage.Add("Head", simplifyScriptBlock); 3779 } 3780 3781 string vwoUrl = PageView.Current().AreaSettings.GetItem("Custom").GetRawValueString("VWOUrl"); 3782 string vwoId = PageView.Current().AreaSettings.GetItem("Custom").GetRawValueString("VWOId"); 3783 3784 if (!string.IsNullOrEmpty(vwoId) && !string.IsNullOrEmpty(vwoUrl)) 3785 { 3786 Block vwoScriptBlock = new Block() 3787 { 3788 Id = "VWOScript", 3789 SortId = 5, 3790 Template = RenderVWOScript(vwoId, vwoUrl) 3791 }; 3792 3793 topSnippetsBlocksPage.Add("Head", vwoScriptBlock); 3794 } 3795 3796 string triplePixelTripleName = PageView.Current().AreaSettings.GetItem("Custom").GetRawValueString("TriplePixelTripleName"); 3797 3798 if (!string.IsNullOrEmpty(triplePixelTripleName)) 3799 { 3800 Block triplePixelScriptBlock = new Block() 3801 { 3802 Id = "TriplePixelScript", 3803 SortId = 6, 3804 Template = RenderTriplePixelScript(triplePixelTripleName) 3805 }; 3806 3807 topSnippetsBlocksPage.Add("Head", triplePixelScriptBlock); 3808 } 3809 3810 ItemViewModel customSommifySettings = PageView.Current().AreaSettings.GetItem("Custom").GetItem("SommifySettings"); 3811 if (customSommifySettings != null) 3812 { 3813 bool sommifyActivated = customSommifySettings.GetBoolean("ActivateSommify"); 3814 if (sommifyActivated) 3815 { 3816 Block sommifyScriptBlock = new Block() 3817 { 3818 Id = "SommifyScript", 3819 SortId = 5, 3820 Template = RenderSommifyScript(customSommifySettings) 3821 }; 3822 3823 topSnippetsBlocksPage.Add("Head", sommifyScriptBlock); 3824 } 3825 } 3826 3827 string spriiScript = PageView.Current().AreaSettings.GetItem("Custom").GetRawValueString("SpriiScript"); 3828 if (!string.IsNullOrEmpty(spriiScript)) 3829 { 3830 Block spriiScriptBlock = new Block() 3831 { 3832 Id = "SpriiScript", 3833 SortId = 5, 3834 Template = RenderSpriiScript(spriiScript) 3835 }; 3836 3837 topSnippetsBlocksPage.Add("Head", spriiScriptBlock); 3838 } 3839 3840 string klaviyoId = Custom.Klaviyo.Helpers.Helper.GetKlaviyoId(Pageview, "Settings"); 3841 if (!string.IsNullOrEmpty(klaviyoId)) 3842 { 3843 Block klaviyoScriptBlock = new Block() 3844 { 3845 Id = "KlaviyoScript", 3846 SortId = 10, 3847 Template = RenderKlaviyoScript(klaviyoId) 3848 }; 3849 3850 topSnippetsBlocksPage.Add("Head", klaviyoScriptBlock); 3851 } 3852 3853 if (RecaptchaHelper.RecaptchaActivated) 3854 { 3855 Block recaptchaScriptBlock = new Block() 3856 { 3857 Id = "RecaptchaScript", 3858 SortId = 5, 3859 Template = RenderRecaptchaScript() 3860 }; 3861 3862 topSnippetsBlocksPage.Add("Head", recaptchaScriptBlock); 3863 } 3864 3865 ItemViewModel customInternationalTelephoneSettings = PageView.Current().AreaSettings.GetItem("Custom").GetItem("InternationalTelephoneSettings"); 3866 if (customInternationalTelephoneSettings != null) 3867 { 3868 bool internationalTelephoneActivated = customInternationalTelephoneSettings.GetBoolean("ActivateInternationalTelephone"); 3869 if (internationalTelephoneActivated) 3870 { 3871 Block internationalTelephoneScriptBlock = new Block() 3872 { 3873 Id = "InternationalTelephoneScript", 3874 SortId = 5, 3875 Template = RenderInternationalTelephoneScript(customInternationalTelephoneSettings) 3876 }; 3877 3878 topSnippetsBlocksPage.Add("Head", internationalTelephoneScriptBlock); 3879 } 3880 } 3881 3882 Block schemaBlock = new Block() 3883 { 3884 Id = "SchemaBlock", 3885 SortId = 100, 3886 Template = RenderSchema() 3887 }; 3888 3889 topSnippetsBlocksPage.Add("Head", schemaBlock); 3890 3891 bool isProductPage = PageView.Current().Page.ID == GetPageIdByNavigationTag("ProductsPage"); 3892 if (isProductPage) 3893 { 3894 ItemViewModel productMapSettings = PageView.Current().AreaSettings.GetItem("Custom").GetItem("ProductMapSettings"); 3895 if (productMapSettings != null) 3896 { 3897 bool activateInteractiveMap = productMapSettings.GetBoolean("ActivateInteractiveMap"); 3898 string mapStylesheet = productMapSettings.GetRawValueString("MapStylesheet"); 3899 string mapStylesheetIntegrity = productMapSettings.GetRawValueString("MapStylesheetIntegrity"); 3900 string mapScript = productMapSettings.GetRawValueString("MapScript"); 3901 string mapScriptIntegrity = productMapSettings.GetRawValueString("MapScriptIntegrity"); 3902 if (activateInteractiveMap 3903 && !string.IsNullOrWhiteSpace(mapStylesheet) 3904 && !string.IsNullOrWhiteSpace(mapStylesheetIntegrity) 3905 && !string.IsNullOrWhiteSpace(mapScript) 3906 && !string.IsNullOrWhiteSpace(mapScriptIntegrity) 3907 ) 3908 { 3909 Block mapBlock = new Block() 3910 { 3911 Id = "MapBlock", 3912 SortId = 100, 3913 Template = RenderMap(mapStylesheet, mapStylesheetIntegrity, mapScript, mapScriptIntegrity) 3914 }; 3915 3916 topSnippetsBlocksPage.Add("Head", mapBlock); 3917 } 3918 } 3919 } 3920 3921 string htmxScriptSource = PageView.Current().AreaSettings.GetItem("Custom").GetRawValueString("HTMXScriptSource"); 3922 string htmxScriptIntegrity = PageView.Current().AreaSettings.GetItem("Custom").GetRawValueString("HTMXScriptIntegrity"); 3923 if (!string.IsNullOrWhiteSpace(htmxScriptSource) && !string.IsNullOrWhiteSpace(htmxScriptIntegrity)) 3924 { 3925 Block htmxBlock = new Block() 3926 { 3927 Id = "HTMXBlock", 3928 SortId = 100, 3929 Template = RenderHTMXScript(htmxScriptSource, htmxScriptIntegrity) 3930 }; 3931 3932 topSnippetsBlocksPage.Add("Head", htmxBlock); 3933 } 3934 } 3935 3936 @helper RenderCookieInformation() 3937 { 3938 <script id="CookieConsent" src="https://policy.app.cookieinformation.com/uc.js" data-culture="@Pageview.Area.CultureInfo.TwoLetterISOLanguageName.ToUpper()" data-gcm-version="2.0" type="text/javascript"></script> 3939 3940 <script type="text/javascript"> 3941 window.addEventListener('CookieInformationConsentGiven', function (event) { 3942 if (!CookieInformation.getConsentGivenFor('cookie_cat_marketing')) { 3943 var allFrames = document.querySelectorAll("iframe"); 3944 3945 //Start - Content replacing iframes 3946 for (i = 0; i < allFrames.length; i++) { 3947 var frame = allFrames[i]; 3948 if (frame.src.indexOf('youtu') !== -1 || frame.src.indexOf('vimeo') !== -1) { 3949 frame.insertAdjacentHTML("beforebegin", '<div class="consent-placeholder u-brand-color-two" data-category="cookie_cat_marketing" onClick="CookieConsent.renew()">@Translate("Smartpage:Cookieinformation.Renew", "Renew or change your cookie consent to see this content")</div>'); 3950 frame.parentNode.removeChild(frame); 3951 } 3952 } 3953 } 3954 // Google Consent mode implementation 3955 if (CookieInformation.getConsentGivenFor('cookie_cat_statistic') && window.gtag != undefined) { 3956 gtag('consent', 'update', { 'analytics_storage': 'granted' }); 3957 } 3958 if (CookieInformation.getConsentGivenFor('cookie_cat_marketing') && window.gtag != undefined) { 3959 gtag('consent', 'update', { 'ad_storage': 'granted' }); 3960 } 3961 3962 window.dataLayer = window.dataLayer || []; 3963 window.dataLayer.push({ 'event': 'consent_decision_made' }); 3964 }, false); 3965 3966 </script> 3967 } 3968 3969 @helper RenderSimplifyScript(string id) 3970 { 3971 <script type="text/javascript"> 3972 window.addEventListener('CookieInformationConsentGiven', function (event) { 3973 if (CookieInformation.getConsentGivenFor('cookie_cat_statistic')) { 3974 var script = document.createElement('script'); 3975 script.setAttribute('type', 'text/javascript'); 3976 script.setAttribute('src', 'https://cdn-sitegainer.com/@id/es6/index.bundle.js'); 3977 document.head.appendChild(script); 3978 } 3979 }, false); 3980 </script> 3981 } 3982 3983 @helper RenderVWOScript(string vwoId, string vwoUrl) 3984 { 3985 <link rel="preconnect" href="@vwoUrl" /> 3986 <script type='text/javascript' id='vwoCode'> 3987 window._vwo_code || (function () { 3988 var account_id = @vwoId, 3989 version = 2.1, 3990 settings_tolerance = 2000, 3991 hide_element = 'body', 3992 hide_element_style = 'opacity:0 !important;filter:alpha(opacity=0) !important;background:none !important', 3993 f = false, w = window, d = document, v = d.querySelector('#vwoCode'), cK = '_vwo_' + account_id + '_settings', cc = {}; try { var c = JSON.parse(localStorage.getItem('_vwo_' + account_id + '_config')); cc = c && typeof c === 'object' ? c : {} } catch (e) { } var stT = cc.stT === 'session' ? w.sessionStorage : w.localStorage; code = { use_existing_jquery: function () { return typeof use_existing_jquery !== 'undefined' ? use_existing_jquery : undefined }, library_tolerance: function () { return typeof library_tolerance !== 'undefined' ? library_tolerance : undefined }, settings_tolerance: function () { return cc.sT || settings_tolerance }, hide_element_style: function () { return '{' + (cc.hES || hide_element_style) + '}' }, hide_element: function () { if (performance.getEntriesByName('first-contentful-paint')[0]) { return '' } return typeof cc.hE === 'string' ? cc.hE : hide_element }, getVersion: function () { return version }, finish: function (e) { if (!f) { f = true; var t = d.getElementById('_vis_opt_path_hides'); if (t) t.parentNode.removeChild(t); if (e) (new Image).src = '@vwoUrl/ee.gif?a=' + account_id + e } }, finished: function () { return f }, addScript: function (e) { var t = d.createElement('script'); t.type = 'text/javascript'; if (e.src) { t.src = e.src } else { t.text = e.text } d.getElementsByTagName('head')[0].appendChild(t) }, load: function (e, t) { var i = this.getSettings(), n = d.createElement('script'), r = this; t = t || {}; if (i) { n.textContent = i; d.getElementsByTagName('head')[0].appendChild(n); if (!w.VWO || VWO.caE) { stT.removeItem(cK); r.load(e) } } else { var o = new XMLHttpRequest; o.open('GET', e, true); o.withCredentials = !t.dSC; o.responseType = t.responseType || 'text'; o.onload = function () { if (t.onloadCb) { return t.onloadCb(o, e) } if (o.status === 200) { _vwo_code.addScript({ text: o.responseText }) } else { _vwo_code.finish('&e=loading_failure:' + e) } }; o.onerror = function () { if (t.onerrorCb) { return t.onerrorCb(e) } _vwo_code.finish('&e=loading_failure:' + e) }; o.send() } }, getSettings: function () { try { var e = stT.getItem(cK); if (!e) { return } e = JSON.parse(e); if (Date.now() > e.e) { stT.removeItem(cK); return } return e.s } catch (e) { return } }, init: function () { if (d.URL.indexOf('__vwo_disable__') > -1) return; var e = this.settings_tolerance(); w._vwo_settings_timer = setTimeout(function () { _vwo_code.finish(); stT.removeItem(cK) }, e); var t; if (this.hide_element() !== 'body') { t = d.createElement('style'); var i = this.hide_element(), n = i ? i + this.hide_element_style() : '', r = d.getElementsByTagName('head')[0]; t.setAttribute('id', '_vis_opt_path_hides'); v && t.setAttribute('nonce', v.nonce); t.setAttribute('type', 'text/css'); if (t.styleSheet) t.styleSheet.cssText = n; else t.appendChild(d.createTextNode(n)); r.appendChild(t) } else { t = d.getElementsByTagName('head')[0]; var n = d.createElement('div'); n.style.cssText = 'z-index: 2147483647 !important;position: fixed !important;left: 0 !important;top: 0 !important;width: 100% !important;height: 100% !important;background: white !important;'; n.setAttribute('id', '_vis_opt_path_hides'); n.classList.add('_vis_hide_layer'); t.parentNode.insertBefore(n, t.nextSibling) } var o = '@vwoUrl/j.php?a=' + account_id + '&u=' + encodeURIComponent(d.URL) + '&vn=' + version; if (w.location.search.indexOf('_vwo_xhr') !== -1) { this.addScript({ src: o }) } else { this.load(o + '&x=true') } } }; w._vwo_code = code; code.init(); 3994 })(); 3995 </script> 3996 } 3997 3998 @helper RenderTriplePixelScript(string tripleName) 3999 { 4000 <link rel='preconnect dns-prefetch' href='https://api.config-security.com/' crossorigin /> 4001 <link rel='preconnect dns-prefetch' href='https://conf.config-security.com/' crossorigin /> 4002 <script> 4003 /* >> TriplePixel :: start*/ 4004 window.TriplePixelData={TripleName:"@tripleName",ver:"2.17",plat:"custom-msp",isHeadless:true},function(W,H,A,L,E,_,B,N){function O(U,T,P,H,R){void 0===R&&(R=!1),H=new XMLHttpRequest,P?(H.open("POST",U,!0),H.setRequestHeader("Content-Type","text/plain")):H.open("GET",U,!0),H.send(JSON.stringify(P||{})),H.onreadystatechange=function(){4===H.readyState&&200===H.status?(R=H.responseText,U.includes("/first")?eval(R):P||(N[B]=R)):(299<H.status||H.status<200)&&T&&!R&&(R=!0,O(U,T-1,P))}}if(N=window,!N[H+"sn"]){N[H+"sn"]=1,L=function(){return Date.now().toString(36)+"_"+Math.random().toString(36)};try{A.setItem(H,1+(0|A.getItem(H)||0)),(E=JSON.parse(A.getItem(H+"U")||"[]")).push({u:location.href,r:document.referrer,t:Date.now(),id:L()}),A.setItem(H+"U",JSON.stringify(E))}catch(e){}var i,m,p;A.getItem('"!nC`')||(_=A,A=N,A[H]||(E=A[H]=function(t,e,a){return void 0===a&&(a=[]),"State"==t?E.s:(W=L(),(E._q=E._q||[]).push([W,t,e].concat(a)),W)},E.s="Installed",E._q=[],E.ch=W,B="configSecurityConfModel",N[B]=1,O("https://conf.config-security.com/model",5),i=L(),m=A[atob("c2NyZWVu")],_.setItem("di_pmt_wt",i),p={id:i,action:"profile",avatar:_.getItem("auth-security_rand_salt_"),time:m[atob("d2lkdGg=")]+":"+m[atob("aGVpZ2h0")],host:A.TriplePixelData.TripleName,plat:A.TriplePixelData.plat,url:window.location.href.slice(0,500),ref:document.referrer,ver:A.TriplePixelData.ver},O("https://api.config-security.com/event",5,p),O("https://api.config-security.com/first?host=@tripleName&plat=custom-msp",5)))}}("","TriplePixel",localStorage); 4005 /* << TriplePixel :: end*/ 4006 </script> 4007 } 4008 4009 @helper RenderSommifyScript(ItemViewModel customSommifySettings) 4010 { 4011 string sommifyUrl = customSommifySettings.GetRawValueString("SommifyUrl"); 4012 4013 if (!string.IsNullOrEmpty(sommifyUrl)) 4014 { 4015 <script id="sommifyScript" async src="@sommifyUrl"></script> 4016 } 4017 } 4018 4019 @helper RenderSpriiScript(string spriiScript) 4020 { 4021 <script src="@spriiScript" type="module" crossorigin="anonymous" async></script> 4022 } 4023 4024 @helper RenderRecaptchaScript() 4025 { 4026 string combinedSrc = RecaptchaHelper.RecaptchaScript + "?render=" + RecaptchaHelper.RecaptchaSiteKey; 4027 <script class="js-recaptcha-script" src="@HttpUtility.HtmlAttributeEncode(combinedSrc)"></script> 4028 } 4029 4030 @helper RenderInternationalTelephoneScript(ItemViewModel customInternationalTelephoneSettings) 4031 { 4032 string styleSheetUrl = customInternationalTelephoneSettings.GetRawValueString("StyleSheetUrl"); 4033 string minifiedJsUrl = customInternationalTelephoneSettings.GetRawValueString("MinifiedJsUrl"); 4034 string utilsJsUrl = customInternationalTelephoneSettings.GetRawValueString("UtilsJsUrl"); 4035 4036 if (!string.IsNullOrEmpty(styleSheetUrl) && !string.IsNullOrEmpty(minifiedJsUrl) && !string.IsNullOrEmpty(utilsJsUrl)) 4037 { 4038 <link id="internationalTelephoneStylesheet" async rel="stylesheet" href="@styleSheetUrl"> 4039 <script id="internationalTelephoneScriptMinified" async src="@minifiedJsUrl"></script> 4040 } 4041 } 4042 4043 @helper RenderGoogleConsentMode() 4044 { 4045 <script> 4046 window.dataLayer = window.dataLayer || []; 4047 function gtag() { dataLayer.push(arguments); } 4048 gtag('consent', 'default', { 4049 'ad_storage': 'denied', 4050 'ad_user_data': 'denied', 4051 'ad_personalization': 'denied', 4052 'analytics_storage': 'denied', 4053 'wait_for_update': 500 4054 }); 4055 gtag('set', 'ads_data_redaction', true); 4056 </script> 4057 } 4058 4059 @helper RenderGoogleAnalyticsSnippet() 4060 { 4061 <!-- Global site tag (gtag.js) - Google Analytics --> 4062 <script async src="https://www.googletagmanager.com/gtag/js?id=@GoogleAnalyticsID"></script> 4063 <script> 4064 window.dataLayer = window.dataLayer || []; 4065 function gtag(){dataLayer.push(arguments);} 4066 gtag('js', new Date()); 4067 4068 gtag('config', '@GoogleAnalyticsID'); 4069 </script> 4070 } 4071 4072 @helper RenderGTMDataLayer() 4073 { 4074 string anonymousId = HttpContext.Current.Request.Cookies["ajs_anonymous_id"]?.Value ?? "undefined"; 4075 var currentUser = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser(); 4076 if (currentUser != null) 4077 { 4078 <script> 4079 window.dataLayer = window.dataLayer || []; 4080 window.dataLayer = [{ 4081 'event': 'Active on site', 4082 'attributes': { 4083 'properties': { 4084 'userStatus': 'loggedIn', 4085 'userId': '@currentUser.ID', 4086 'customerType': '@GetCustomUserFieldValue("AccessUser_SpBcCustomerType")', 4087 'customerName': '@currentUser.Name', 4088 'email': '@currentUser.Email', 4089 'mobile': '@currentUser.Phone', 4090 'countryPhoneCode': '@GetCustomUserFieldValue("AccessUser_SpCountryPhoneCode")', 4091 'rawPhoneNumber': '@GetCustomUserFieldValue("AccessUser_SpRawPhoneNumber")', 4092 'combinedPhoneNumber': '@GetCustomUserFieldValue("AccessUser_SpCombinedPhoneNumber")', 4093 'bcId': '@currentUser.CustomerNumber', 4094 'customerCountry': '@currentUser.CountryCode', 4095 'page': '@(HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + HttpContext.Current.Request.RawUrl)', 4096 'deviceCategory': '@Convert.ToString(Pageview.Device)', 4097 'address': { 4098 'country': '@currentUser.CountryCode', 4099 'city': '@currentUser.City', 4100 'postalCode': '@currentUser.Zip', 4101 'street': '@HttpUtility.JavaScriptStringEncode(currentUser.Address)' 4102 } 4103 }, 4104 'time': '@DateTime.Now.ToString("G", System.Globalization.CultureInfo.InvariantCulture)', 4105 'uniqueId': '@Guid.NewGuid().ToString("N")', 4106 'shopId': '@Pageview.Area.EcomShopId', 4107 'areaId': '@Converter.ToString(Pageview.AreaID)', 4108 'ajsAnonymousID': '@anonymousId' 4109 } 4110 }]; 4111 </script> 4112 } 4113 else 4114 { 4115 <script> 4116 window.dataLayer = window.dataLayer || []; 4117 window.dataLayer = [{ 4118 'userStatus': 'notLoggedIn', 4119 'userId': undefined, 4120 'customerType': undefined, 4121 'shopId': '@Pageview.Area.EcomShopId', 4122 'areaId': '@Converter.ToString(Pageview.AreaID)', 4123 'ajsAnonymousID': '@anonymousId' 4124 }] 4125 </script> 4126 } 4127 } 4128 4129 @helper RenderDataLayerHelpers() 4130 { 4131 string loginEventSession = Dynamicweb.Context.Current.Session["custom_login_event"]?.ToString() ?? ""; 4132 4133 // Clear session immediately after reading 4134 if (!string.IsNullOrEmpty(loginEventSession)) 4135 { 4136 Dynamicweb.Context.Current.Session.Remove("custom_login_event"); 4137 } 4138 4139 <script> 4140 function setDatalayerLogin(loginData) { 4141 window.dataLayer = window.dataLayer || []; 4142 window.dataLayer.push({ 4143 'event': 'login', 4144 'method': loginData.method || 'email', 4145 'user_id': loginData.user_id, 4146 'customer_number': loginData.customer_number, 4147 'email': loginData.email, 4148 'shop_id': loginData.shop_id, 4149 'device': loginData.device, 4150 'page_location': window.location.href 4151 }); 4152 } 4153 4154 @if (!string.IsNullOrEmpty(loginEventSession)) 4155 { 4156 <text> 4157 // Auto-trigger login event from session data 4158 (function() { 4159 try { 4160 var loginData = JSON.parse('@HttpUtility.JavaScriptStringEncode(loginEventSession)'); 4161 setDatalayerLogin(loginData); 4162 } catch (e) { 4163 console.error('Error parsing login event data:', e); 4164 } 4165 })(); 4166 </text> 4167 } 4168 </script> 4169 } 4170 4171 @helper RenderGoogleTagManager() 4172 { 4173 string googleTagManagerSource = "https://gtm.philipsonwine.com"; 4174 if (!string.IsNullOrEmpty(Model.Area.Item.GetItem("Settings").GetString("SpGoogleTagManagerSource"))) 4175 { 4176 googleTagManagerSource = Model.Area.Item.GetItem("Settings").GetString("SpGoogleTagManagerSource"); 4177 } 4178 <script> 4179 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 4180 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 4181 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 4182 '@googleTagManagerSource?id='+i+dl;f.parentNode.insertBefore(j,f); 4183 })(window,document,'script','dataLayer','@GoogleTagManagerID'); 4184 </script> 4185 } 4186 4187 4188 4189 @helper RenderGoogleTagManagerBodySnippet() 4190 { 4191 string source = !string.IsNullOrEmpty(Model.Area.Item.GetItem("Settings").GetString("SpGoogleTagManagerBodySnippetSource")) ? Model.Area.Item.GetItem("Settings").GetString("SpGoogleTagManagerBodySnippetSource") : "https://www.googletagmanager.com/ns.html"; 4192 <!-- Google Tag Manager (noscript) --> 4193 <noscript> 4194 <iframe src="@source?id=@GoogleTagManagerID" 4195 height="0" width="0" style="display:none;visibility:hidden"></iframe> 4196 </noscript> 4197 <!-- End Google Tag Manager (noscript) --> 4198 } 4199 4200 @helper RenderFacebookPixel() 4201 { 4202 string FacebookPixelID = Model.Area.Item.GetItem("Settings").GetString("FacebookPixelID"); 4203 4204 if (!string.IsNullOrWhiteSpace(FacebookPixelID)) 4205 { 4206 <!-- Facebook Pixel Code --> 4207 <script> 4208 !function(f,b,e,v,n,t,s) 4209 {if(f.fbq)return;n=f.fbq=function(){n.callMethod? 4210 n.callMethod.apply(n,arguments):n.queue.push(arguments)}; 4211 if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0'; 4212 n.queue=[];t=b.createElement(e);t.async=!0; 4213 t.src=v;s=b.getElementsByTagName(e)[0]; 4214 s.parentNode.insertBefore(t,s)}(window, document,'script', 4215 'https://connect.facebook.net/en_US/fbevents.js'); 4216 fbq('init', '@FacebookPixelID'); 4217 fbq('track', 'PageView'); 4218 </script> 4219 <noscript><img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=@FacebookPixelID&ev=PageView&noscript=1" alt="" /></noscript> 4220 } 4221 } 4222 4223 4224 @helper RenderFacebookPixelProductPage() 4225 { 4226 string FacebookPixelID = Model.Area.Item.GetItem("Settings").GetString("FacebookPixelID"); 4227 string productId = Dynamicweb.Context.Current.Request["ProductId"]; 4228 bool isProductPage = !string.IsNullOrEmpty(productId); 4229 4230 if (!string.IsNullOrWhiteSpace(FacebookPixelID) && isProductPage) 4231 { 4232 var product = Dynamicweb.Ecommerce.Services.Products.GetProductById(productId, string.Empty, true); 4233 if (product != null) 4234 { 4235 <!-- Facebook Pixel Code --> 4236 <script> 4237 fbq('track', 'ViewContent', { 4238 content_ids: '@product.Id', 4239 content_type: 'product', 4240 value: '@product.UnformattedPrice.ToString().Replace(',','.')', 4241 currency: '@Dynamicweb.Ecommerce.Common.Context.Currency.Symbol.Trim()', 4242 content_category: '@Converter.ToString(product.ProductFieldValues.GetProductFieldValue("SpWineDescription")?.Value)' 4243 }); 4244 </script> 4245 } 4246 } 4247 } 4248 4249 @helper RenderOneSignalScript() 4250 { 4251 string oneSignalAppId = Model.Area.Item.GetItem("Settings").GetString("SpOneSignalAppId"); 4252 if (!string.IsNullOrEmpty(oneSignalAppId)) 4253 { 4254 <script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async=""></script> 4255 <script> 4256 window.OneSignal = window.OneSignal || []; 4257 OneSignal.push(function() { 4258 OneSignal.init({ 4259 appId: "@oneSignalAppId", 4260 }); 4261 }); 4262 </script> 4263 } 4264 } 4265 4266 @helper RenderOpenSearchReference() 4267 { 4268 <link type="application/opensearchdescription+xml" rel="search" href="https://philipsonwine.com/Files/opensearch.xml" /> 4269 } 4270 4271 @helper TrustpilotScript() 4272 { 4273 <script type="text/javascript" src="//widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js" async></script> 4274 } 4275 4276 @helper RenderKlaviyoScript(string id) 4277 { 4278 <script async type="text/javascript" src="https://static.klaviyo.com/onsite/js/klaviyo.js?company_id=@(id)"></script> 4279 } 4280 4281 @helper RenderSchema() 4282 { 4283 var schemaSettings = PageView.Current().AreaSettings.GetItem("CustomSchema"); 4284 var currentUrl = Dynamicweb.Context.Current.Request.Url.Scheme + "://" + Dynamicweb.Context.Current.Request.Url.Host + Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?Id=" + PageView.Current().Page.ID); 4285 var language = PageView.Current().Area.CultureInfo.TwoLetterISOLanguageName; 4286 var returnPolicies = schemaSettings.GetItems("ReturnPolicies"); 4287 var certifications = schemaSettings.GetItems("Certifications"); 4288 var openingHours = schemaSettings.GetItems("OpeningHours"); 4289 var isProductPage = PageView.Current().Page.ID == GetPageIdByNavigationTag("ProductsPage"); 4290 4291 <script type="application/ld+json"> 4292 { 4293 "@@context": "https://schema.org", 4294 "@@graph": [ 4295 @if (!isProductPage) 4296 { 4297 <text> 4298 { 4299 "@@type": "WebPage", 4300 "@@id": "@currentUrl", 4301 "url": "@currentUrl", 4302 "name": "@PageView.Current().Page.GetDisplayName()", 4303 "description": "@PageView.Current().Page.Description", 4304 "inLanguage": "@language", 4305 "keywords": "@PageView.Current().Page.Keywords", 4306 "primaryImageOfPage": "https://philipsonwine.com/Files/Images/philipsonwine/logo/philipson-wine-logo.svg", 4307 @if(!string.IsNullOrEmpty(schemaSettings.GetRawValueString("WebPageSignificantLinks"))) 4308 { 4309 var index = 0; 4310 <text> 4311 "significantLink": [ 4312 @foreach (var link in schemaSettings.GetRawValueString("WebPageSignificantLinks").Split(',')) 4313 { 4314 <text> 4315 "@link" 4316 </text> 4317 index++; 4318 if (index < schemaSettings.GetRawValueString("WebPageSignificantLinks").Split(',').Count()) 4319 { 4320 <text>,</text> 4321 } 4322 } 4323 4324 ], 4325 </text> 4326 } 4327 "isPartOf": { 4328 "@@id": "https://philipsonwine.com/#website" 4329 } 4330 }, 4331 </text> 4332 } 4333 { 4334 "@@type": "WebSite", 4335 "@@id": "https://philipsonwine.com/#website", 4336 "url": "https://philipsonwine.com/", 4337 "name": "Philipson Wine", 4338 @if (!string.IsNullOrEmpty(schemaSettings.GetRawValueString("WebsiteDescription"))) 4339 { 4340 <text> 4341 "description": "@schemaSettings.GetRawValueString("WebsiteDescription")", 4342 </text> 4343 } 4344 "inLanguage": "da", 4345 "author": "Philipson Wine ApS", 4346 "copyrightHolder": "Philipson Wine ApS", 4347 @if (!string.IsNullOrEmpty(schemaSettings.GetRawValueString("WebSiteSearchActionTarget"))) 4348 { 4349 <text> 4350 "potentialAction": { 4351 "@@type": "SearchAction", 4352 "target": "@schemaSettings.GetRawValueString("WebSiteSearchActionTarget"){search_term_string}", 4353 "query-input": "required name=search_term_string" 4354 }, 4355 </text> 4356 } 4357 "publisher": { 4358 "@@id": "https://philipsonwine.com/#organization" 4359 } 4360 }, 4361 { 4362 "@@type": "OnlineStore", 4363 "@@id": "https://philipsonwine.com/#organization", 4364 "name": "Philipson Wine", 4365 "alternateName": "PW", 4366 "legalName": "Philipson Wine ApS", 4367 "url": "https://philipsonwine.com/", 4368 "logo": "https://philipsonwine.com/Files/Images/philipsonwine/logo/philipson-wine-logo.svg", 4369 "description": "@schemaSettings.GetRawValueString("OnlineStoreDescription", "Velkommen til Philipson Wine - din førende vinhandel med mere end 35 års erfaring inden for vinbranchen. Vi er stolte af vores lange historie, vores tætte samarbejde med samtlige anerkendte vinproducenter verden over og af at vi er eneimportør af nogle af de mest kendte producenter")", 4370 "email": "@schemaSettings.GetRawValueString("OnlineStoreEmail", "support@philipsonwine.com")", 4371 "telephone": "@schemaSettings.GetRawValueString("OnlineStoreTelephone", "+4570226888")", 4372 "foundingDate": "1987-01-01", 4373 "founder": "Christian Philipson", 4374 "numberOfEmployees": { 4375 "@@type": "QuantitativeValue", 4376 "value": @schemaSettings.GetInt32("OnlineStoreEmployees") 4377 }, 4378 "vatID": "@schemaSettings.GetRawValueString("OnlineStoreVatID", "DK28331843")", 4379 "address": { 4380 "@@type": "PostalAddress", 4381 "streetAddress": "@schemaSettings.GetRawValueString("OnlineStoreAddress", "Kokkedal Industripark 10")", 4382 "addressLocality": "@schemaSettings.GetRawValueString("OnlineStoreCity", "Kokkedal")", 4383 "postalCode": "@schemaSettings.GetRawValueString("OnlineStoreZip", "2980")", 4384 "addressCountry": "@schemaSettings.GetRawValueString("OnlineStoreCountryCode", "DK")" 4385 }, 4386 "aggregateRating": { 4387 "@@type": "AggregateRating", 4388 "name": "TrustPilot", 4389 "url": "https://dk.trustpilot.com/review/www.philipsonwine.com", 4390 "ratingValue": "4.2", 4391 "bestRating": "5", 4392 "worstRating": "1", 4393 "reviewCount": "10851" 4394 }, 4395 "hasMerchantReturnPolicy": [ 4396 @if (returnPolicies.Any()) 4397 { 4398 var index = 0; 4399 foreach (var returnPolicy in returnPolicies) 4400 { 4401 <text> 4402 { 4403 "@@type": "MerchantReturnPolicy", 4404 "returnPolicyCategory": "@returnPolicy.GetRawValueString("ReturnPolicyCategory")", 4405 "merchantReturnDays": "@returnPolicy.GetInt32("MerchantReturnDays")", 4406 "returnMethod": "@returnPolicy.GetRawValueString("ReturnMethod")", 4407 "returnFees": "@returnPolicy.GetRawValueString("ReturnFees")", 4408 "refundType": "@returnPolicy.GetRawValueString("RefundType")", 4409 "applicableCountry": "@returnPolicy.GetRawValueString("ApplicableCountry")" 4410 } 4411 </text> 4412 index++; 4413 4414 if (index < returnPolicies.Count) 4415 { 4416 <text>,</text> 4417 } 4418 } 4419 } 4420 ], 4421 "contactPoint": { 4422 "@@type": "ContactPoint", 4423 "telephone": "@schemaSettings.GetRawValueString("OnlineStoreTelephone", "+4570226888")", 4424 "email": "@schemaSettings.GetRawValueString("OnlineStoreEmail", "support@philipsonwine.com")", 4425 "contactType": "customer service", 4426 "areaServed": "DK" 4427 }, 4428 @if (!string.IsNullOrEmpty(schemaSettings.GetRawValueString("OnlineStoreSameAs"))) 4429 { 4430 var sameAsList = schemaSettings.GetRawValueString("OnlineStoreSameAs").Split(','); 4431 var index = 0; 4432 <text> 4433 "sameAs": [ 4434 @foreach (var sameAs in sameAsList) 4435 { 4436 <text> 4437 "@sameAs" 4438 </text> 4439 index++; 4440 if (index < sameAsList.Count()) 4441 { 4442 <text>,</text> 4443 } 4444 } 4445 ], 4446 </text> 4447 } 4448 "department": { 4449 "@@type": "LiquorStore", 4450 "name": "@schemaSettings.GetRawValueString("DepartmentName", "Philipson Wine Butik")", 4451 "@@id": "https://philipsonwine.com/#LiquorStore", 4452 "url": "https://philipsonwine.com/", 4453 "telephone": "@schemaSettings.GetRawValueString("DepartmentTelephone", "+4570226888")", 4454 "priceRange": "$$", 4455 "currenciesAccepted": "@schemaSettings.GetRawValueString("DepartmentCurrenciesAccepted", "DKK")", 4456 "paymentAccepted": "@schemaSettings.GetRawValueString("DepartmentPaymentsAccepted", "Cash, Credit Card, MobilePay")", 4457 "brand": { 4458 "@@id": "https://philipsonwine.com/#organization" 4459 }, 4460 "knowsLanguage": [ 4461 @{ 4462 var lanCount = 0; 4463 } 4464 4465 @foreach (var knownLang in schemaSettings.GetRawValueString("DepartmentKnownLanguages", "da,en").Split(',').ToList()) 4466 { 4467 <text> 4468 "@knownLang" 4469 </text> 4470 lanCount++; 4471 if (lanCount < schemaSettings.GetRawValueString("DepartmentKnownLanguages", "da,en").Split(',').ToList().Count()) 4472 { 4473 <text>,</text> 4474 } 4475 } 4476 4477 ], 4478 "hasCertification": [ 4479 @if(certifications.Any()) 4480 { 4481 var index = 0; 4482 4483 foreach (var certification in certifications) 4484 { 4485 <text> 4486 { 4487 "@@type": "Certification", 4488 "name": "@certification.GetRawValueString("Name")", 4489 "description": "@certification.GetRawValueString("Description")", 4490 "certificationStatus": "@certification.GetRawValueString("Status")", 4491 "url": "@certification.GetRawValueString("Link")", 4492 "certificationIdentification": "@certification.GetRawValueString("Identification")", 4493 "logo": "@certification.GetRawValueString("Logo")", 4494 "issuedBy": { 4495 "@@type": "Organization", 4496 "name": "@certification.GetRawValueString("IssuerName")", 4497 "url": "@certification.GetRawValueString("IssuerUrl")" 4498 } 4499 } 4500 </text> 4501 index++; 4502 if (index < certifications.Count) 4503 { 4504 <text>,</text> 4505 } 4506 } 4507 } 4508 ], 4509 "address": { 4510 "@@type": "PostalAddress", 4511 "streetAddress": "@schemaSettings.GetRawValueString("DepartmentAddress", "Kokkedal Industripark 10")", 4512 "addressLocality": "@schemaSettings.GetRawValueString("DepartmentCity", "Kokkedal")", 4513 "postalCode": "@schemaSettings.GetRawValueString("DepartmentZip", "2980")", 4514 "addressCountry": "@schemaSettings.GetRawValueString("DepartmentCountryCode", "DK")" 4515 }, 4516 @{ 4517 var location = schemaSettings.GetRawValueString("DepartmentLocation", "55.90391229999999;12.4796683").Split(';'); 4518 } 4519 "geo": { 4520 "@@type": "GeoCoordinates", 4521 "latitude": @location.First(), 4522 "longitude": @location.Last() 4523 }, 4524 "openingHoursSpecification": [ 4525 @if (openingHours.Any()) 4526 { 4527 var index = 0; 4528 4529 foreach (var openingHour in openingHours) 4530 { 4531 var days = openingHour.GetRawValueString("Weekdays").Split(',').ToList(); 4532 <text> 4533 { 4534 "@@type": "OpeningHoursSpecification", 4535 "dayOfWeek": @if(days.Count() > 1) 4536 { 4537 <text> 4538 [ 4539 @{ 4540 var dayCount = 0; 4541 } 4542 @foreach(var day in days) 4543 { 4544 <text> 4545 "@day" 4546 </text> 4547 dayCount++; 4548 if (dayCount < days.Count()) 4549 { 4550 <text>,</text> 4551 } 4552 } 4553 ], 4554 </text> 4555 } 4556 else 4557 { 4558 <text>"@days.First()",</text> 4559 } 4560 "opens": "@openingHour.GetRawValueString("Opens")", 4561 "closes": "@openingHour.GetRawValueString("Closes")" 4562 } 4563 </text> 4564 index++; 4565 if (index < openingHours.Count) 4566 { 4567 <text>,</text> 4568 } 4569 } 4570 } 4571 ] 4572 } 4573 } 4574 ] 4575 } 4576 </script> 4577 } 4578 4579 @helper RenderMap(string mapStylesheet, string mapStylesheetIntegrity, string mapScript, string mapScriptIntegrity) 4580 { 4581 <link rel="stylesheet" href="@HttpUtility.HtmlAttributeEncode(mapStylesheet)" integrity="@HttpUtility.HtmlAttributeEncode(mapStylesheetIntegrity)" crossorigin="" /> 4582 <script type="text/javascript" src="@HttpUtility.HtmlAttributeEncode(mapScript)" integrity="@HttpUtility.HtmlAttributeEncode(mapScriptIntegrity)" crossorigin=""></script> 4583 } 4584 4585 @helper RenderHTMXScript(string src, string integrity) 4586 { 4587 <script type="text/javascript" src="@HttpUtility.HtmlAttributeEncode(src)" integrity="@HttpUtility.HtmlAttributeEncode(integrity)" crossorigin="anonymous"></script> 4588 } 4589 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 4590 4591 @using System 4592 @using System.Web 4593 @using System.Collections.Generic 4594 @using Dynamicweb.Rapido.Blocks 4595 @using Dynamicweb.Rapido.Blocks.Extensibility 4596 @using Dynamicweb.Security.UserManagement 4597 @using Dynamicweb.Security.UserManagement.ExternalAuthentication 4598 @using Dynamicweb.Rapido.Blocks.Components.General 4599 @using Smartpage.Segment.Providers; 4600 4601 @{ 4602 BlocksPage loginBlocksPage = BlocksPage.GetBlockPage("Master"); 4603 4604 Block loginModal = new Block() 4605 { 4606 Id = "LoginModal", 4607 SortId = 10, 4608 Component = new Modal 4609 { 4610 Id = "SignIn", 4611 Heading = new Heading 4612 { 4613 Level = 0, 4614 Title = Translate("Sign in") 4615 }, 4616 Width = ModalWidth.Xs, 4617 BodyTemplate = RenderLoginForm() 4618 } 4619 }; 4620 4621 loginBlocksPage.Add(MasterBlockId.MasterTopSnippets, loginModal); 4622 } 4623 4624 @helper RenderLoginForm() 4625 { 4626 int pageId = Model.TopPage.ID; 4627 int currentPageId = Pageview.ID; 4628 string userSignedInErrorText = ""; 4629 int signInProfilePageId = GetPageIdByNavigationTag("SignInPage"); 4630 int cartPageId = GetPageIdByNavigationTag("CartPage"); 4631 string forgotPasswordPageLink = "/Default.aspx?ID=" + signInProfilePageId + "&LoginAction=Recovery"; 4632 int createAccountPageId = GetPageIdByNavigationTag("CreateAccount"); 4633 bool showModalOnStart = pageId != GetPageIdByNavigationTag("CustomerCenter") && Model.LogOnFailed; 4634 bool hideCreateAccountLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideCreateAccount"); 4635 bool hideForgotPasswordLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideForgotPasswordLink"); 4636 string cartLogin = currentPageId == cartPageId ? "True" : "False"; 4637 4638 if (Model.LogOnFailed) 4639 { 4640 switch (Model.LogOnFailedReason) 4641 { 4642 case LogOnFailedReason.PasswordLengthInvalid: 4643 userSignedInErrorText = Translate("Password length is invalid"); 4644 break; 4645 case LogOnFailedReason.IncorrectLogin: 4646 userSignedInErrorText = Translate("Invalid email or password"); 4647 break; 4648 case LogOnFailedReason.ExceededFailedLogOnLimit: 4649 userSignedInErrorText = Translate("You have exceeded the limit of allowed login attempts. The user account is temporarily locked"); 4650 break; 4651 case LogOnFailedReason.LoginLocked: 4652 userSignedInErrorText = Translate("The user account is temporarily locked"); 4653 break; 4654 case LogOnFailedReason.PasswordExpired: 4655 userSignedInErrorText = Translate("The password has expired and needs to be renewed"); 4656 break; 4657 default: 4658 userSignedInErrorText = Translate("An unknown error occured"); 4659 break; 4660 } 4661 } 4662 4663 Form form = new Form { Method = FormMethod.Post, Name = "LoginModalForm", CssClass = "u-hidden js-login-form" }; 4664 4665 if (Model.LogOnFailed && !string.IsNullOrWhiteSpace(userSignedInErrorText)) 4666 { 4667 string ajsAnonymousId = HttpContext.Current.Request.Cookies["ajs_anonymous_id"] != null ? HttpContext.Current.Request.Cookies["ajs_anonymous_id"].Value : "undefined"; 4668 var failedLoginProperties = new Dictionary<string, object>() 4669 { 4670 { "logOnFailedReason", userSignedInErrorText }, 4671 { "device", Pageview.Device.ToString() }, 4672 { "ajsAnonymousId", ajsAnonymousId } 4673 }; 4674 AnalyticsProvider.Track(null, "Failed Login", failedLoginProperties, Dynamicweb.Frontend.PageView.Current().Area.EcomShopId, null); 4675 } 4676 4677 if (currentPageId == cartPageId) 4678 { 4679 form.Action = "/Default.aspx?ID=" + GetPageIdByNavigationTag("CheckoutPage"); 4680 } 4681 4682 form.Add(new HiddenField { Name = "ID", Value = Converter.ToString(pageId) }); 4683 form.Add(new HiddenField { Name = "DWExtranetUsernameRemember", Value = "True" }); 4684 form.Add(new HiddenField { Name = "DWExtranetPasswordRemember", Value = "True" }); 4685 form.Add(new HiddenField { Name = "LoginAction", Value = "Login" }); 4686 form.Add(new HiddenField { Name = "CartLogin", Value = cartLogin }); 4687 form.Add(new TextField { Id = "LoginUsername", Name = "username", Label = Translate("Email"), CssClass = "u-full-width", Required = true }); 4688 form.Add(new TextField { Id = "LoginPassword", Name = "password", Type = TextFieldType.Password, Label = Translate("Password"), CssClass = "u-full-width", Required = true }); 4689 form.Add(new NotificationMessage { Message = userSignedInErrorText, MessageType = NotificationMessageType.Error }); 4690 form.Add(new CheckboxField { Id = "LoginRememberMe", Value = "True", Name = "Autologin", Label = Translate("Remember me") }); 4691 form.Add(new Button { ButtonType = ButtonType.Submit, Title = Translate("Sign in"), CssClass = "btn--full", OnClick = "Buttons.LockButton(event)" }); 4692 4693 if (!hideCreateAccountLink) 4694 { 4695 form.Add(new Link { Href = "/default.aspx?ID=" + createAccountPageId, Title = Translate("Create account?"), ButtonLayout = ButtonLayout.None, CssClass = "u-block u-padding-bottom" }); 4696 } 4697 4698 if (!hideForgotPasswordLink) 4699 { 4700 form.Add(new Link { Href = forgotPasswordPageLink, Title = Translate("Forgot your password?"), ButtonLayout = ButtonLayout.None, CssClass = "u-block u-padding-bottom" }); 4701 } 4702 4703 @Render(form) 4704 4705 if (showModalOnStart) 4706 { 4707 <script> 4708 document.getElementById("SignInModalTrigger").checked = true; 4709 document.querySelector('.js-login-form')?.classList.remove('u-hidden'); 4710 </script> 4711 } 4712 } 4713 4714 @if (!isHeaderHidden) 4715 { 4716 if (Pageview.Device != Dynamicweb.Frontend.Devices.DeviceType.Desktop) 4717 { 4718 <text>@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 4719 @using System 4720 @using System.Web 4721 @using System.Collections.Generic 4722 @using Dynamicweb.Rapido.Blocks.Extensibility 4723 @using Dynamicweb.Rapido.Blocks 4724 @using Smartpage.PhilipsonWine.Ecommerce.CartInformation; 4725 @using Smartpage.PhilipsonWine.LiveShopper.Models; 4726 @using Dynamicweb.Frontend 4727 4728 @functions { 4729 BlocksPage mobileHeaderBlocksPage = BlocksPage.GetBlockPage("Master"); 4730 } 4731 4732 @{ 4733 var mobileTopLayout = !String.IsNullOrEmpty(Model.Area.Item.GetItem("Layout").GetItem("MobileTop").GetString("Design")) ? Model.Area.Item.GetItem("Layout").GetItem("MobileTop").GetList("Design").SelectedValue : "nav-left"; 4734 bool mobileHideSearch = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("HideSearch"); 4735 bool mobileHideCart = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("HideCart") || !Dynamicweb.Rapido.Services.User.IsBuyingAllowed(); 4736 4737 if (Pageview.Device != Dynamicweb.Frontend.Devices.DeviceType.Desktop) 4738 { 4739 Block mobileHeader = new Block() 4740 { 4741 Id = "MobileTop", 4742 SortId = 10, 4743 Template = RenderMobileTop(), 4744 SkipRenderBlocksList = true 4745 }; 4746 mobileHeaderBlocksPage.Add(MasterBlockId.MasterHeader, mobileHeader); 4747 } 4748 4749 Block mobileHeaderNavigation = new Block() 4750 { 4751 Id = "MobileHeaderNavigation", 4752 SortId = 10, 4753 Template = RenderMobileHeaderNavigation(), 4754 SkipRenderBlocksList = true 4755 }; 4756 mobileHeaderBlocksPage.Add("MobileTop", mobileHeaderNavigation); 4757 4758 Block mobileHeaderLogo = new Block() 4759 { 4760 Id = "MobileHeaderLogo", 4761 SortId = 20, 4762 Template = RenderMobileHeaderLogo(), 4763 SkipRenderBlocksList = true 4764 }; 4765 mobileHeaderBlocksPage.Add("MobileTop", mobileHeaderLogo); 4766 4767 Block mobileHeaderActions = new Block() 4768 { 4769 Id = "MobileHeaderActions", 4770 SortId = 30, 4771 Template = RenderMobileTopActions(), 4772 SkipRenderBlocksList = true 4773 }; 4774 mobileHeaderBlocksPage.Add("MobileTop", mobileHeaderActions); 4775 4776 Block mobileHeaderNavigationTriggerBlock = new Block() 4777 { 4778 Id = "MobileHeaderNavigationTrigger", 4779 SortId = 10, 4780 Template = RenderMobileHeaderNavigationTrigger() 4781 }; 4782 mobileHeaderBlocksPage.Add("MobileTop", mobileHeaderNavigationTriggerBlock); 4783 4784 Block mobileHeaderMiniCart; 4785 4786 if (!mobileHideCart) 4787 { 4788 mobileHeaderMiniCart = new Block 4789 { 4790 Id = "MobileHeaderMiniCart", 4791 SortId = 20, 4792 Template = RenderMobileTopMiniCart() 4793 }; 4794 4795 Block miniCartCounterScriptTemplate = new Block 4796 { 4797 Id = "MiniCartCounterScriptTemplate", 4798 Template = RenderMobileMiniCartCounterContent() 4799 }; 4800 BlocksPage.GetBlockPage("Master").Add("MasterBottomSnippets", miniCartCounterScriptTemplate); 4801 } 4802 else 4803 { 4804 mobileHeaderMiniCart = new Block 4805 { 4806 Id = "MobileHeaderMiniCart", 4807 SortId = 20 4808 }; 4809 } 4810 4811 Block mobileHeaderCustomerCenterBlock = new Block 4812 { 4813 Id = "MobileHeaderCustomerCenter", 4814 SortId = 10, 4815 Template = RenderMobileCustomerCenterAction() 4816 }; 4817 mobileHeaderBlocksPage.Add("MobileHeaderActions", mobileHeaderCustomerCenterBlock); 4818 4819 switch (mobileTopLayout) 4820 { 4821 case "nav-left": 4822 mobileHeaderNavigation.SortId = 10; 4823 mobileHeaderLogo.SortId = 20; 4824 mobileHeaderActions.SortId = 30; 4825 mobileHeaderNavigationTriggerBlock.SortId = 30; 4826 mobileHeaderBlocksPage.Add("MobileHeaderActions", mobileHeaderMiniCart); 4827 break; 4828 case "nav-right": 4829 mobileHeaderLogo.SortId = 10; 4830 mobileHeaderActions.SortId = 20; 4831 mobileHeaderNavigation.SortId = 30; 4832 mobileHeaderNavigationTriggerBlock.SortId = 30; 4833 mobileHeaderBlocksPage.Add("MobileHeaderActions", mobileHeaderMiniCart); 4834 break; 4835 case "nav-search-left": 4836 mobileHeaderNavigation.SortId = 10; 4837 mobileHeaderLogo.SortId = 20; 4838 mobileHeaderActions.SortId = 30; 4839 mobileHeaderNavigationTriggerBlock.SortId = 30; 4840 mobileHeaderBlocksPage.Add("MobileHeaderNavigation", mobileHeaderMiniCart); 4841 break; 4842 case "search-left": 4843 mobileHeaderActions.SortId = 10; 4844 mobileHeaderLogo.SortId = 20; 4845 mobileHeaderNavigation.SortId = 30; 4846 mobileHeaderMiniCart.SortId = 0; 4847 mobileHeaderNavigationTriggerBlock.SortId = 30; 4848 mobileHeaderBlocksPage.Add("MobileHeaderNavigation", mobileHeaderMiniCart); 4849 break; 4850 case "custom": 4851 mobileHeaderActions.SortId = 100; 4852 mobileHeaderLogo.SortId = 30; 4853 mobileHeaderNavigation.SortId = 20; 4854 mobileHeaderMiniCart.SortId = 50; 4855 mobileHeaderNavigationTriggerBlock.SortId = 10; 4856 mobileHeaderBlocksPage.Add("MobileHeaderActions", mobileHeaderMiniCart); 4857 break; 4858 } 4859 4860 if (Pageview.Page.NavigationTag == "CartPage") 4861 { 4862 Block mobileCheckoutUsp = new Block 4863 { 4864 Id = "MobileCheckoutUsp", 4865 SortId = 50, 4866 Template = RenderMobileCheckoutUsp() 4867 }; 4868 mobileHeaderBlocksPage.Add(MasterBlockId.MasterHeader, mobileCheckoutUsp); 4869 } 4870 } 4871 4872 4873 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 4874 4875 @using System 4876 @using System.Web 4877 @using Dynamicweb.Rapido.Blocks.Extensibility 4878 @using Dynamicweb.Rapido.Blocks 4879 4880 @{ 4881 BlocksPage customMobileHeaderBlocksPage = BlocksPage.GetBlockPage("Master"); 4882 } 4883 4884 @helper RenderMobileTop() 4885 { 4886 List<Block> subBlocks = this.mobileHeaderBlocksPage.GetBlockListById("MobileTop").OrderBy(item => item.SortId).ToList(); 4887 var mobileTopLayout = !String.IsNullOrEmpty(Model.Area.Item.GetItem("Layout").GetItem("MobileTop").GetString("Design")) ? Model.Area.Item.GetItem("Layout").GetItem("MobileTop").GetList("Design").SelectedValue : "nav-left"; 4888 DateTime now = DateTime.Now; 4889 var upcomingEvent = Dynamicweb.Context.Current.Application["SpLiveShopperEvent"] as Event; 4890 bool isEventLive = upcomingEvent != null && upcomingEvent.Start > now && upcomingEvent.End < now; 4891 ItemViewModel sommifySettings = PageView.Current().AreaSettings.GetItem("Custom").GetItem("SommifySettings"); 4892 bool sommifyIsActive = false; 4893 if (sommifySettings != null) 4894 { 4895 bool activateSommify = sommifySettings.GetBoolean("ActivateSommify"); 4896 string sommifyApiKey = sommifySettings.GetRawValueString("SommifyApiKey"); 4897 sommifyIsActive = activateSommify && !string.IsNullOrEmpty(sommifyApiKey); 4898 } 4899 4900 var promoBarSettings = Model.Area.Item.GetItem("Custom").GetItem("PromoBarSettings"); 4901 4902 <nav class="main-navigation-mobile dw-mod js-navigation-mobile js-main-navigation-mobile @mobileTopLayout" data-use-retractable-menu="@Model.Area.Item.GetItem("Custom").GetBoolean("RetractableMenu")"> 4903 <div class="center-container top-container__center-container dw-mod"> 4904 <div class="grid grid--align-center"> 4905 @RenderBlockList(subBlocks) 4906 </div> 4907 </div> 4908 <div class="navigation-search-container"> 4909 <div class="mobile-navigation-search-button header js-open-search" style="@(sommifyIsActive ? "border-radius: 10px 0px 0px 10px;" : "")"> 4910 <i class="far fa-search"></i> 4911 <p>@Translate("Smartpage:MobilMenu.SearchButtonText", "Søg efter produkter eller indhold")</p> 4912 </div> 4913 @if (sommifyIsActive) 4914 { 4915 string sommifyIcon = sommifySettings.GetRawValueString("SommifyIcon"); 4916 string sommifyBackgroundColor = sommifySettings.GetRawValueString("SommifyBackgroundColor"); 4917 string sommifyStyling = !string.IsNullOrEmpty(sommifyBackgroundColor) ? "background-color: " + sommifyBackgroundColor + ";" : ""; 4918 4919 <div class="header-menu__link header-menu__link--icon sommify-header-container js-sommify-widget-activator dw-mod" style="@sommifyStyling"> 4920 <div class="custom__header__icon__icon"> 4921 @if (!string.IsNullOrEmpty(sommifyIcon)) 4922 { 4923 <img class="sommify-header-icon" src="@sommifyIcon" /> 4924 } 4925 </div> 4926 <div class="custom__header__icon__text sommify-header-text"> 4927 @Translate("Smartpage:Header.Sommify.Text", "Wine AI") 4928 </div> 4929 </div> 4930 } 4931 </div> 4932 @if (upcomingEvent != null && isEventLive) 4933 { 4934 <div class="liveshopping-mobile"> 4935 <div class="pulsating-circle"></div> 4936 <a href="/Default.aspx?ID=@GetPageIdByNavigationTag("LiveshoppingPage")"> 4937 @Translate("Smartpage:Header.LiveshoppingTextMobile", "Vi sender LIVE nu!") 4938 </a> 4939 </div> 4940 } 4941 @if (promoBarSettings != null) 4942 { 4943 var promoBarContent = promoBarSettings.GetItems("PromoBarContent"); 4944 if (promoBarContent != null && promoBarContent.Any()) 4945 { 4946 @RenderPromoBar(promoBarSettings, promoBarContent) 4947 } 4948 } 4949 </nav> 4950 } 4951 4952 @helper RenderMobileHeaderNavigation() 4953 { 4954 List<Block> subBlocks = this.mobileHeaderBlocksPage.GetBlockListById("MobileHeaderNavigation").OrderBy(item => item.SortId).ToList(); 4955 if (subBlocks.Any()) 4956 { 4957 <div class="grid__col-auto-width"> 4958 <ul class="menu dw-mod"> 4959 @RenderBlockList(subBlocks) 4960 </ul> 4961 </div> 4962 } 4963 } 4964 4965 @helper RenderMobileHeaderNavigationTrigger() 4966 { 4967 <li class="mobile-navigation-trigger js-mobile-navigation-trigger"> 4968 <label for="MobileNavTrigger" class="mobile-nav-trigger-button menu__link menu__link--icon menu__link--mobile dw-mod"></label> 4969 </li> 4970 } 4971 4972 @helper RenderMobileHeaderLogo() 4973 { 4974 List<Block> subBlocks = this.mobileHeaderBlocksPage.GetBlockListById("MobileHeaderLogo").OrderBy(item => item.SortId).ToList(); 4975 4976 var mobileTopLayout = !String.IsNullOrEmpty(Model.Area.Item.GetItem("Layout").GetItem("MobileTop").GetString("Design")) ? Model.Area.Item.GetItem("Layout").GetItem("MobileTop").GetList("Design").SelectedValue : "nav-left"; 4977 string centeredLogo = mobileTopLayout != "nav-right" ? "u-ta-center" : ""; 4978 string firstPageId = Model.Area.FirstActivePage.ID.ToString(); 4979 string businessName = Model.Area.Item.GetItem("Settings").GetString("BusinessName"); 4980 4981 string mobileLogo = "/Files/Images/logo-dynamicweb.png"; 4982 if (Model.Area.Item.GetItem("Layout").GetItem("MobileTop") != null && Model.Area.Item.GetItem("Layout").GetItem("MobileTop").GetFile("Logo") != null) 4983 { 4984 mobileLogo = Model.Area.Item.GetItem("Layout").GetItem("MobileTop").GetFile("Logo").PathUrlEncoded; 4985 } 4986 4987 if (Path.GetExtension(mobileLogo).ToLower() != ".svg") 4988 { 4989 mobileLogo = "/Admin/Public/GetImage.ashx?height=40&amp;width=100&amp;crop=5&amp;Compression=75&amp;image=" + mobileLogo; 4990 } 4991 else 4992 { 4993 mobileLogo = HttpUtility.UrlDecode(mobileLogo); 4994 } 4995 4996 if (mobileTopLayout == "custom") 4997 { 4998 centeredLogo = "u-flex"; 4999 } 5000 5001 <div class="grid__col-auto grid__col--bleed"> 5002 <div class="grid--justify-center grid__cell @centeredLogo"> 5003 <a href="/Default.aspx?ID=@firstPageId" class="logo logo--mobile u-inline-block dw-mod"> 5004 <img class="grid__cell-img logo__img logo__img--mobile dw-mod" src="@mobileLogo" alt="@businessName" /> 5005 </a> 5006 </div> 5007 5008 @RenderBlockList(subBlocks) 5009 </div> 5010 } 5011 5012 @helper RenderMobileTopActions() 5013 { 5014 List<Block> subBlocks = this.mobileHeaderBlocksPage.GetBlockListById("MobileHeaderActions").OrderBy(item => item.SortId).ToList(); 5015 5016 <div class="u-no-padding grid__col-6"> 5017 <ul class="grid mobile-top-actions"> 5018 @RenderBlockList(subBlocks) 5019 </ul> 5020 </div> 5021 } 5022 5023 @helper RenderMobileCustomerCenterAction() 5024 { 5025 var user = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser(); 5026 5027 if (user != null) 5028 { 5029 string customerDashboardLink = "/Default.aspx?Id=" + GetPageIdByNavigationTag("CustomerDashboard"); 5030 <li class="grid__col-auto mobile-top-actions__action"> 5031 <a href="@customerDashboardLink" class="menu__link menu__link--icon menu__link--mobile dw-mod"> 5032 @RenderProfileIcon() 5033 <span class="menu__link__text">@Translate("Smartpage:MobileHeader.Profile", "Profil")</span> 5034 </a> 5035 </li> 5036 } 5037 else 5038 { 5039 <li class="grid__col-auto mobile-top-actions__action"> 5040 <label for="SignInModalTrigger" class="menu__link menu__link--icon menu__link--mobile dw-mod js-sign-in-modal-trigger"> 5041 @RenderProfileIcon() 5042 <span class="menu__link__text">@Translate("Smartpage:MobileHeader.Login", "Login")</span> 5043 </label> 5044 </li> 5045 } 5046 5047 } 5048 5049 @helper RenderProfileIcon() 5050 { 5051 <?xml version="1.0" encoding="UTF-8" ?> 5052 <svg width="16px" height="20px" viewBox="0 0 16 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 5053 <title>60DACE7C-4BF5-4F9F-93C4-F806A7E060C8</title> 5054 <g id="Philipson-Wine" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 5055 <g id="Mobil---ny-header" transform="translate(-228.000000, -11.000000)" fill="#2A4A3A" fill-rule="nonzero"> 5056 <g id="Login-mobile" transform="translate(228.000000, 11.000000)"> 5057 <path d="M7.87692308,0 C5.4726297,0 3.52629696,1.94633274 3.52629696,4.35062612 C3.52629696,6.7549195 5.4726297,8.70125224 7.87692308,8.70125224 C10.2812165,8.70125224 12.2275492,6.7549195 12.2275492,4.35062612 C12.2275492,1.94633274 10.2812165,0 7.87692308,0 Z" id="Path"></path> 5058 <path d="M9.57137746,10.6003578 L6.18246869,10.6003578 C2.7706619,10.6003578 0,13.3710197 0,16.7828265 L0,19.30161 C0,19.6908766 0.297674419,19.988551 0.686940966,19.988551 L15.0669052,19.988551 C15.4561717,19.988551 15.7538462,19.6908766 15.7538462,19.30161 L15.7538462,16.7828265 C15.7538462,13.3710197 12.9831843,10.6003578 9.57137746,10.6003578 Z" id="Path"></path> 5059 </g> 5060 </g> 5061 </g> 5062 </svg> 5063 } 5064 5065 @helper RenderMobileTopMiniCart() 5066 { 5067 int miniCartFeedPageId = GetPageIdByNavigationTag("MiniCartFeed"); 5068 int cartPageId = GetPageIdByNavigationTag("CartPage"); 5069 double cartProductsCount = 0; 5070 string totalPrice = 0.ToString("N2"); 5071 string showCounterClass = "u-hidden"; 5072 5073 if (Model != null && Model.Cart != null && Model.Cart.CartOrderlines != null) 5074 { 5075 CartInformation cartInformation = new CartInformation(Model.Cart); 5076 5077 cartProductsCount = cartInformation.OrderLineCount; 5078 totalPrice = Model.Cart.TotalPrice.Price.Formatted; 5079 showCounterClass = string.Empty; 5080 } 5081 5082 <li class="grid__col-auto mobile-top-actions__action mobile-top-actions__action--mini-cart" id="miniCartWrapper"> 5083 <div class="mini-cart dw-mod"> 5084 <a href="/Default.aspx?ID=@cartPageId" id="miniCartCounterWrap" class="menu__link menu__link--icon menu__link--mobile dw-mod js-mini-cart-button"> 5085 <div class="u-inline u-position-relative"> 5086 <?xml version="1.0" encoding="UTF-8" ?> 5087 <svg width="27px" height="23px" viewBox="0 0 27 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 5088 <title>684ADC2E-E513-4391-ABAF-ED9723E87695</title> 5089 <g id="Philipson-Wine" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 5090 <g id="Mobil---ny-header" transform="translate(-327.000000, -8.000000)" fill="#2A4A3A"> 5091 <path d="M350.342987,22.2387411 L353.077072,12.1651775 C353.114836,11.998797 353.074565,11.8242713 352.967708,11.6912695 C352.856522,11.5719381 352.704894,11.4982887 352.542387,11.4846752 L332.273764,11.4846752 L330.888495,8.44182719 C330.844749,8.16203921 330.586037,7.96803313 330.305223,8.00437367 L327,8.00437367 L327,9.11013998 L329.952811,9.11013998 L331.301626,12.152988 L334.035711,22.2387411 L334.10862,22.4331459 L335.056436,25.8841871 C334.161821,26.361 333.611928,27.3009555 333.634712,28.3145034 L333.634712,28.8734529 L333.695488,28.8734529 C333.939334,30.1096578 335.023741,31.0005706 336.283755,31.000055 C337.775597,31.0066653 338.992321,29.8062883 339.005707,28.3144465 C338.990442,27.744162 338.799454,27.1924465 338.45889,26.7347722 L345.907732,26.7347722 C345.571497,27.1939275 345.384839,27.7454721 345.373048,28.3144465 C345.386434,29.8062883 346.603101,31.0066653 348.095,31.000055 C349.355014,31.0005137 350.439421,30.1096008 350.683267,28.8734529 L350.744043,28.8734529 L350.744043,28.3145034 C350.757486,26.8448191 349.576931,25.6425624 348.107303,25.6291198 C348.099158,25.6290628 348.091013,25.6290059 348.082868,25.6290059 L336.283755,25.6290059 L336.101483,25.6290059 L335.639707,23.9035137 C335.84727,23.9723785 336.065085,24.0052445 336.283755,24.0007446 L348.082811,24.0007446 C349.149161,23.9955043 350.077781,23.2715984 350.342987,22.2387411 Z M348.0103,26.6991721 C348.889252,26.6791222 349.617999,27.3754024 349.637992,28.2543536 C349.638448,28.2744035 349.638505,28.2944535 349.63822,28.3145034 C349.638448,29.1728921 348.953161,29.8744126 348.095,29.8941777 L348.082868,29.8820452 C347.203916,29.9020952 346.475169,29.205815 346.455176,28.3268638 C346.435069,27.4479126 347.131349,26.7191651 348.0103,26.6991721 Z M336.332684,26.6987164 C337.211578,26.712216 337.913155,27.4356092 337.899884,28.3145034 C337.907004,29.180183 337.211008,29.8877982 336.345329,29.8949182 C336.324823,29.8950891 336.304261,29.8948613 336.283755,29.8942347 L336.283755,29.8821022 C335.40469,29.8686027 334.703055,29.1449816 334.716612,28.2659734 C334.730168,27.3869653 335.453675,26.6851599 336.332684,26.6987164 Z" id="Cart-mobile"></path> 5092 </g> 5093 </g> 5094 </svg> 5095 <div class="mini-cart__counter dw-mod @showCounterClass"> 5096 <div class="js-handlebars-root js-mini-cart-counter" id="cartCounter" data-template="MiniCartCounterContent" data-json-feed="/Default.aspx?ID=@miniCartFeedPageId&feedType=Counter" data-init-onload="false" data-preloader="false"> 5097 <div class="js-mini-cart-counter-content u-ta-center" data-count="@cartProductsCount"> 5098 @cartProductsCount 5099 </div> 5100 </div> 5101 </div> 5102 </div> 5103 </a> 5104 <div class="js-handlebars-root js-mini-cart-counter u-ta-center" id="cartCounterPrice" data-template="MiniCartCounterPrice" data-json-feed="/Default.aspx?ID=@miniCartFeedPageId&feedType=Counter" data-init-onload="false" data-preloader="false"> 5105 <span class="menu__link__text js-mini-cart-total-price">@totalPrice</span> 5106 </div> 5107 </div> 5108 </li> 5109 } 5110 5111 @helper RenderMobileMiniCartCounterContent() 5112 { 5113 <script id="MiniCartCounterContent" type="text/x-template"> 5114 {{#.}} 5115 <div class="js-mini-cart-counter-content dw-mod" data-count="{{numberofproducts}}"> 5116 {{numberofproducts}} 5117 </div> 5118 {{/.}} 5119 </script> 5120 5121 <script id="MiniCartCounterPrice" type="text/x-template"> 5122 {{#.}} 5123 <span class="menu__link__text js-mini-cart-total-price">{{totalprice}}</span> 5124 {{/.}} 5125 </script> 5126 } 5127 5128 @helper RenderMobileCheckoutUsp() 5129 { 5130 <div class="custom__checkout__headerusp usp-swiper-container"> 5131 <div class="swiper-wrapper"> 5132 @RenderMobileUsp("help", Translate("Smartpage:Checkout.Brug for hælp?", "Brug for hælp?"), Translate("Smartpage:Checkout.Tel: 70 22 68 88", "Tel: 70 22 68 88")) 5133 @RenderMobileUsp("Secure", Translate("Smartpage:Checkout.Sikker betaling", "Sikker betaling"), Translate("Smartpage:Checkout.Krypteret betaling", "Krypteret betaling")) 5134 @RenderMobileUsp("delivery", Translate("Smartpage:Checkout.Hurtig levering", "Hurtig levering"), Translate("Smartpage:Checkout.1-2 dages levering", "1-2 dages levering")) 5135 @RenderMobileUsp("tilfredshed", Translate("Smartpage:Checkout.100% tilfredshed!", "100% tilfredshed!"), Translate("Smartpage:Checkout.Du kan nemt sende retur", "Du kan nemt sende retur")) 5136 </div> 5137 </div> 5138 } 5139 5140 @helper RenderMobileUsp(string icon, string toptext, string bottomtext) 5141 { 5142 string svg = icon + ".svg"; 5143 5144 <div class="swiper-slide"> 5145 <div class="u-flex u-padding"> 5146 <div class="u-margin-right"> 5147 <img src="/Files/Images/SvgIcons/@svg" height="28" width="28" /> 5148 </div> 5149 <div class="swiper-slide__text-section"> 5150 <div class="u-block"> 5151 <strong>@toptext</strong> 5152 </div> 5153 <div class="u-block"> 5154 @bottomtext 5155 </div> 5156 </div> 5157 </div> 5158 </div> 5159 } 5160 </text> 5161 <text>@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 5162 @using System 5163 @using System.Web 5164 @using System.Collections.Generic 5165 @using Dynamicweb.Rapido.Blocks.Extensibility 5166 @using Dynamicweb.Rapido.Blocks 5167 @using System.Text.RegularExpressions 5168 @using Dynamicweb.Ecommerce.International 5169 @using Dynamicweb.Core 5170 @using Custom.PhilipsonWine.Security.Helpers 5171 5172 @functions { 5173 BlocksPage mobileNavigationBlocksPage = BlocksPage.GetBlockPage("Master"); 5174 } 5175 5176 @{ 5177 bool mobileNavigationItemsHideSignIn = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("HideSignIn"); 5178 bool mobileHideCreateAccountLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideCreateAccount"); 5179 bool mobileHideMyProfileLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideProfile"); 5180 bool mobileHideMyOrdersLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideOrders"); 5181 bool mobileHideMySavedCardsLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideSavedCards"); 5182 bool mobileHideMyFavoritesLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideFavorites"); 5183 bool mobileHideCustomerStockLink = false; 5184 5185 List<Currency> currencies = Dynamicweb.Ecommerce.Services.Currencies.GetCurrenciesForLanguage(Dynamicweb.Ecommerce.Common.Context.LanguageID).ToList(); 5186 5187 Block mobileNavigation = new Block() 5188 { 5189 Id = "MobileNavigation", 5190 SortId = 10, 5191 Template = MobileNavigation(currencies), 5192 SkipRenderBlocksList = true 5193 }; 5194 mobileNavigationBlocksPage.Add(MasterBlockId.MasterTopSnippets, mobileNavigation); 5195 5196 if (Model.CurrentUser.ID > 0 && !mobileHideMyProfileLink) 5197 { 5198 Block mobileNavigationSignIn = new Block 5199 { 5200 Id = "MobileNavigationSignIn", 5201 SortId = 10, 5202 Template = RenderMobileNavigationSignIn() 5203 }; 5204 mobileNavigationBlocksPage.Add("MobileNavigation", mobileNavigationSignIn); 5205 } 5206 5207 Block mobileNavigationMenu = new Block 5208 { 5209 Id = "MobileNavigationMenu", 5210 SortId = 20, 5211 Template = RenderMobileNavigationMenu() 5212 }; 5213 mobileNavigationBlocksPage.Add("MobileNavigation", mobileNavigationMenu); 5214 5215 Block mobileNavigationActions = new Block 5216 { 5217 Id = "MobileNavigationActions", 5218 SortId = 40, 5219 Template = RenderMobileNavigationActions(), 5220 SkipRenderBlocksList = true 5221 }; 5222 mobileNavigationBlocksPage.Add("MobileNavigation", mobileNavigationActions); 5223 5224 NewsletterSignupHelperContext newsletterSignupHelperContext = new NewsletterSignupHelperContext 5225 { 5226 Pageview = Pageview, 5227 GetPageIdByNavigationTag = tag => GetPageIdByNavigationTag(tag), 5228 Translate = (text, def) => Translate(text, def) 5229 }; 5230 5231 Block mobileNavigationNewsletterSignup = new Block 5232 { 5233 Id = "MobileNavigationNewsletterSignup", 5234 SortId = 30, 5235 Template = RenderNewsletterSignUp(newsletterSignupHelperContext, "Sidemenu", Pageview.AreaSettings.GetItem("Custom").GetRawValueString("SignupNewsletterId")), 5236 SkipRenderBlocksList = true 5237 }; 5238 mobileNavigationBlocksPage.Add("MobileNavigation", mobileNavigationNewsletterSignup); 5239 5240 if (!mobileNavigationItemsHideSignIn) 5241 { 5242 if (Model.CurrentUser.ID <= 0) 5243 { 5244 Block mobileNavigationSignInAction = new Block 5245 { 5246 Id = "MobileNavigationSignInAction", 5247 SortId = 10, 5248 Template = RenderMobileNavigationSignInAction() 5249 }; 5250 mobileNavigationBlocksPage.Add("MobileNavigationActions", mobileNavigationSignInAction); 5251 5252 if (!mobileHideCreateAccountLink) 5253 { 5254 Block mobileNavigationCreateAccountAction = new Block 5255 { 5256 Id = "MobileNavigationCreateAccountAction", 5257 SortId = 20, 5258 Template = RenderMobileNavigationCreateAccountAction() 5259 }; 5260 mobileNavigationBlocksPage.Add("MobileNavigationActions", mobileNavigationCreateAccountAction); 5261 } 5262 } 5263 else 5264 { 5265 if (!mobileHideMyOrdersLink) 5266 { 5267 Block mobileNavigationOrdersAction = new Block 5268 { 5269 Id = "MobileNavigationOrdersAction", 5270 SortId = 20, 5271 Template = RenderMobileNavigationOrdersAction() 5272 }; 5273 mobileNavigationBlocksPage.Add("MobileNavigationActions", mobileNavigationOrdersAction); 5274 } 5275 if (!mobileHideMyFavoritesLink) 5276 { 5277 Block mobileNavigationFavoritesAction = new Block 5278 { 5279 Id = "MobileNavigationFavoritesAction", 5280 SortId = 30, 5281 Template = RenderMobileNavigationFavoritesAction() 5282 }; 5283 mobileNavigationBlocksPage.Add("MobileNavigationActions", mobileNavigationFavoritesAction); 5284 } 5285 if (!mobileHideMySavedCardsLink) 5286 { 5287 Block mobileNavigationSavedCardsAction = new Block 5288 { 5289 Id = "MobileNavigationFavoritesAction", 5290 SortId = 30, 5291 Template = RenderMobileNavigationSavedCardsAction() 5292 }; 5293 mobileNavigationBlocksPage.Add("MobileNavigationActions", mobileNavigationSavedCardsAction); 5294 } 5295 5296 if (!mobileHideCustomerStockLink) 5297 { 5298 Block mobileNavigationCustomerStockAction = new Block 5299 { 5300 Id = "MobileNavigationCustomerStockAction", 5301 SortId = 31, 5302 Template = RenderMobileNavigationCustomerStockAction() 5303 }; 5304 mobileNavigationBlocksPage.Add("MobileNavigationActions", mobileNavigationCustomerStockAction); 5305 } 5306 5307 Block mobileNavigationSignOutAction = new Block 5308 { 5309 Id = "MobileNavigationSignOutAction", 5310 SortId = 50, 5311 Template = RenderMobileNavigationSignOutAction() 5312 }; 5313 mobileNavigationBlocksPage.Add("MobileNavigationActions", mobileNavigationSignOutAction); 5314 } 5315 } 5316 5317 var languages = Model.Languages.Where(l => Dynamicweb.Services.Areas.GetArea(l.ID).Published).ToList(); 5318 5319 if (languages.Count > 1) 5320 { 5321 Block mobileNavigationLanguagesAction = new Block 5322 { 5323 Id = "MobileNavigationLanguagesAction", 5324 SortId = 60, 5325 Template = RenderMobileNavigationLanguagesAction(languages) 5326 }; 5327 mobileNavigationBlocksPage.Add("MobileNavigationActions", mobileNavigationLanguagesAction); 5328 } 5329 5330 if (currencies.Count > 1) 5331 { 5332 mobileNavigationBlocksPage.Add("MobileNavigationActions", new Block 5333 { 5334 Id = "MobileNavigationCurrenciesAction", 5335 SortId = 60, 5336 Template = RenderMobileNavigationCurrenciesAction(currencies) 5337 }); 5338 } 5339 } 5340 5341 5342 @helper MobileNavigation(List<Currency> currencies) 5343 { 5344 List<Block> subBlocks = this.mobileNavigationBlocksPage.GetBlockListById("MobileNavigation").OrderBy(item => item.SortId).ToList(); 5345 string mobileTopDesign = Model.Area.Item.GetItem("Layout").GetItem("MobileTop").GetList("Design") != null ? Model.Area.Item.GetItem("Layout").GetItem("MobileTop").GetList("Design").SelectedValue : "nav-left"; 5346 string position = mobileTopDesign == "nav-left" || mobileTopDesign == "nav-search-left" ? "left" : "right"; 5347 5348 <!-- Trigger for mobile navigation --> 5349 <input type="checkbox" id="MobileNavTrigger" class="mobile-nav-trigger mobile-nav-trigger--@position" autocomplete="off" /> 5350 5351 <!-- Mobile navigation --> 5352 <nav class="mobile-navigation mobile-navigation--@position dw-mod js-mobile-navigation"> 5353 <div class="mobile-navigation__wrapper" id="mobileNavigationWrapper"> 5354 <div class="mobile-navigation-header"> 5355 <div class="mobile-navigation-header-topbar"> 5356 <p>@Translate("Smartpage:MobilMenu.headerText", "Brug for hjælp? +45 70 22 68 88")</p> 5357 @if (currencies.Count > 1) 5358 { 5359 bool languageSelectionFromCookie = Dynamicweb.Environment.CookieManager.GetCookie("ActiveLanguageSelection") != null && Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Environment.CookieManager.GetCookie("ActiveLanguageSelection").Value); 5360 <div class="mobile-navigation-header-currency"> 5361 <select onchange="javascript:location.href=this.value;"> 5362 <option disabled selected hidden>@string.Format(Translate("Smartpage:MobilMenu.Currency", "Valuta: {0}"), Dynamicweb.Ecommerce.Common.Context.Currency.Code)</option> 5363 @foreach (Currency currency in currencies) 5364 { 5365 var pageId = Pageview.Page.ID; 5366 5367 if (!languageSelectionFromCookie) 5368 { 5369 5370 var currencyLanguageMapping = Pageview.AreaSettings.GetItem("Custom").GetItems("CurrencyLanguageMapping")?.FirstOrDefault(m => m.GetRawValueString("Currency") == currency.Code); 5371 if (currencyLanguageMapping != null) 5372 { 5373 var language = Model.Languages.FirstOrDefault(l => l.ID == Dynamicweb.Core.Converter.ToInt32(currencyLanguageMapping.GetRawValueString("Language"))); 5374 5375 if (language != null) 5376 { 5377 pageId = language.Page.ID; 5378 } 5379 } 5380 } 5381 var qs = HttpUtility.ParseQueryString(Dynamicweb.Context.Current.Request.QueryString.ToString()); 5382 qs.Set("ID", Converter.ToString(pageId)); 5383 qs.Set("CurrencyCode", currency.Code); 5384 string url = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?" + qs); 5385 5386 <option value="@url">@currency.Code</option> 5387 } 5388 </select> 5389 </div> 5390 } 5391 <div class="mobile-navigation-header-close js-navigation-close"> 5392 <div class="mobile-navigation-header-cross"> 5393 <span></span> 5394 <span></span> 5395 </div> 5396 </div> 5397 </div> 5398 <div class="mobile-navigation-search-button js-open-search"> 5399 <i class="far fa-search"></i> 5400 <p>@Translate("Smartpage:MobilMenu.NavigatioSearchButtonText", "Søg efter produkter eller indhold")</p> 5401 </div> 5402 </div> 5403 @RenderBlockList(subBlocks) 5404 </div> 5405 <div class="mobile-navigation-footer"> 5406 <ul> 5407 @foreach (var icon in Pageview.AreaSettings.GetItem("Custom").GetItem("CustomSettings").GetItems("HeaderUSP")) 5408 { 5409 <li> 5410 @if (!string.IsNullOrWhiteSpace(icon.GetString("Link"))) 5411 { 5412 <a href="@icon.GetString("Link")"><i class="fa fa-check"></i> @icon.GetString("Label")</a> 5413 } 5414 else 5415 { 5416 <i class="fa fa-check"></i> @icon.GetString("Label") 5417 } 5418 </li> 5419 } 5420 </ul> 5421 </div> 5422 </nav> 5423 5424 <div class="search-overlay-header js-overlay-search"> 5425 @RenderOverlaySearchBar() 5426 </div> 5427 5428 <label class="mobile-nav-trigger-off js-mobile-nav-trigger-off" for="MobileNavTrigger"></label> 5429 } 5430 5431 @helper RenderMobileNavigationSignIn() 5432 { 5433 int signInProfilePageId = GetPageIdByNavigationTag("SignInPage"); 5434 int myProfilePageId = GetPageIdByNavigationTag("CustomerProfile"); 5435 string linkStart = Model.CurrentUser.ID <= 0 ? "/Default.aspx?ID=" + signInProfilePageId + "&RedirectPageId=" : "/Default.aspx?ID="; 5436 string myProfilePageLink = linkStart + myProfilePageId; 5437 string userName = Model.CurrentUser.FirstName; 5438 string bonusFormatted = ""; 5439 5440 double bonus = Dynamicweb.Ecommerce.Services.Loyalty.GetPointsBalance(Dynamicweb.Security.UserManagement.User.GetCurrentFrontendUser()); 5441 5442 if (Dynamicweb.Core.Converter.ToDouble(bonus) > 0.0) 5443 { 5444 bonusFormatted = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Common.Context.Currency, bonus); 5445 } 5446 5447 if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(Model.CurrentUser.LastName)) 5448 { 5449 userName += " " + Model.CurrentUser.LastName; 5450 } 5451 if (string.IsNullOrEmpty(userName)) 5452 { 5453 userName = Model.CurrentUser.Name; 5454 } 5455 if (string.IsNullOrEmpty(userName)) 5456 { 5457 userName = Model.CurrentUser.UserName; 5458 } 5459 if (string.IsNullOrEmpty(userName)) 5460 { 5461 userName = Model.CurrentUser.Email; 5462 } 5463 5464 <ul class="menu menu-mobile"> 5465 <li class="menu-mobile__item logged-in-mobile-item"> 5466 <a href="@myProfilePageLink" class="menu-mobile__link dw-mod u-flex--column"> 5467 <span class="u-flex u-flex--row"> 5468 <i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignInProfileIcon").SelectedValue menu-mobile__link-icon"></i> 5469 @userName 5470 </span> 5471 @if (!string.IsNullOrEmpty(bonusFormatted)) 5472 { 5473 <span class="mobile-navigation-description">@Translate("Bonus:") @bonusFormatted</span> 5474 } 5475 </a> 5476 </li> 5477 5478 </ul> 5479 } 5480 5481 @helper RenderMobileNavigationMenu() 5482 { 5483 bool isSlidesDesign = Model.Area.Item.GetItem("Layout").GetItem("MobileNavigation").GetList("Design").SelectedValue == "Slides"; 5484 string menuTemplate = isSlidesDesign ? "BaseMenuForMobileSlides.xslt" : "BaseMenuForMobileExpandable.xslt"; 5485 string levels = !String.IsNullOrEmpty(Model.Area.Item.GetItem("Layout").GetItem("MobileNavigation").GetString("Levels")) ? Model.Area.Item.GetItem("Layout").GetItem("MobileNavigation").GetString("Levels") : "3"; 5486 bool renderPagesInToolBar = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("RenderPagesInToolBar"); 5487 int startLevel = 0; 5488 5489 var navigationSettings = new Dynamicweb.Frontend.Navigation.NavigationSettings() 5490 { 5491 RootAreaId = 0, 5492 RootPageId = 0, 5493 RootNavigationTag = "main-menu", 5494 StartLevel = 1, 5495 StopLevel = 99, 5496 ExpandMode = Dynamicweb.Frontend.Navigation.ExpandMode.All 5497 }; 5498 5499 var navigationTemplate = "Navigation/SpViewModelNavigationMobile.cshtml"; 5500 @Navigation.RenderNavigation(navigationTemplate, navigationSettings) 5501 5502 5503 if (isSlidesDesign) 5504 { 5505 <script> 5506 function goToLevel(level) { 5507 document.getElementById('mobileNavigationWrapper').style.left = -(level * 100) + "%"; 5508 } 5509 5510 document.addEventListener('DOMContentLoaded', function () { 5511 goToLevel(document.getElementById('mobileNavigationWrapper').querySelectorAll('input[type=radio]:checked').length); 5512 }); 5513 </script> 5514 } 5515 5516 if (renderPagesInToolBar) 5517 { 5518 @RenderNavigation(new 5519 { 5520 id = "topToolsMobileNavigation", 5521 cssclass = "menu menu-mobile dwnavigation", 5522 template = "ToolsMenuForMobile.xslt" 5523 }) 5524 } 5525 } 5526 5527 @helper RenderMobileNavigationActions() 5528 { 5529 List<Block> subBlocks = this.mobileNavigationBlocksPage.GetBlockListById("MobileNavigationActions").OrderBy(item => item.SortId).ToList(); ; 5530 5531 <ul class="menu menu-mobile menu-mobile-actions"> 5532 @RenderBlockList(subBlocks) 5533 </ul> 5534 } 5535 5536 @helper RenderMobileNavigationSignInAction() 5537 { 5538 <li class="menu-mobile__item mobile-navigation-login"> 5539 <label for="SignInModalTrigger" onclick="document.getElementById('MobileNavTrigger').checked = false;" class="menu-mobile__link dw-mod menu-mobile__link--highlighted"><i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignInProfileIcon").SelectedValue menu-mobile__link-icon"></i> @Translate("Sign in")</label> 5540 </li> 5541 } 5542 5543 @helper RenderMobileNavigationCreateAccountAction() 5544 { 5545 int createAccountPageId = GetPageIdByNavigationTag("CreateAccount"); 5546 5547 <li class="menu-mobile__item mobile-navigation-create-account"> 5548 <h3>@Translate("Smartpage:MobilMenu.CreateAccountHeading", "Opret bruger og få 100 DKK i opstartsbonus")</h3> 5549 <p>@Translate("Smartpage:MobilMenu.CreateAccountText", "(Gælder på dit næste køb)")</p> 5550 <a class="menu-mobile__link menu-mobile__link--highlighted dw-mod" href="/Default.aspx?ID=@createAccountPageId"><i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignInProfileIcon").SelectedValue menu-mobile__link-icon"></i> @Translate("Create account")</a> 5551 </li> 5552 } 5553 5554 @helper RenderMobileNavigationCustomerStockAction() 5555 { 5556 int customerStockPageId = GetPageIdByNavigationTag("CustomerStockPage"); 5557 5558 <li class="menu-mobile__item logged-in-mobile-item"> 5559 <a class="menu-mobile__link menu-mobile__link--highlighted dw-mod" href="/Default.aspx?ID=@customerStockPageId"><i class="fal fa-clipboard-list menu-mobile__link-icon"></i> @Translate("Smartpage:SignInActions.CustomerStock", "Mit kundelager")</a> 5560 </li> 5561 } 5562 5563 @helper RenderMobileNavigationProfileAction() 5564 { 5565 int signInProfilePageId = GetPageIdByNavigationTag("SignInPage"); 5566 string linkStart = Model.CurrentUser.ID <= 0 ? "/Default.aspx?ID=" + signInProfilePageId + "&RedirectPageId=" : "/Default.aspx?ID="; 5567 int myProfilePageId = GetPageIdByNavigationTag("CustomerProfile"); 5568 string myProfilePageLink = linkStart + myProfilePageId; 5569 5570 <li class="menu-mobile__item logged-in-mobile-item"> 5571 <a href="@myProfilePageLink" class="menu-mobile__link menu-mobile__link--highlighted dw-mod"><i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignInProfileIcon").SelectedValue menu-mobile__link-icon"></i> @Translate("My Profile")</a> 5572 </li> 5573 } 5574 5575 @helper RenderMobileNavigationOrdersAction() 5576 { 5577 int signInProfilePageId = GetPageIdByNavigationTag("SignInPage"); 5578 string linkStart = Model.CurrentUser.ID <= 0 ? "/Default.aspx?ID=" + signInProfilePageId + "&RedirectPageId=" : "/Default.aspx?ID="; 5579 int myOrdersPageId = GetPageIdByNavigationTag("CustomerOrders"); 5580 string myOrdersPageLink = linkStart + myOrdersPageId; 5581 string ordersIcon = "fas fa-list"; 5582 5583 <li class="menu-mobile__item logged-in-mobile-item"> 5584 <a href="@myOrdersPageLink" class="menu-mobile__link menu-mobile__link--highlighted dw-mod"><i class="@ordersIcon menu-mobile__link-icon"></i> @Translate("My Orders")</a> 5585 </li> 5586 } 5587 5588 @helper RenderMobileNavigationFavoritesAction() 5589 { 5590 int signInProfilePageId = GetPageIdByNavigationTag("SignInPage"); 5591 string linkStart = Model.CurrentUser.ID <= 0 ? "/Default.aspx?ID=" + signInProfilePageId + "&RedirectPageId=" : "/Default.aspx?ID="; 5592 int myFavoritesPageId = GetPageIdByNavigationTag("CustomerFavorites"); 5593 string myFavoritesPageLink = linkStart + myFavoritesPageId; 5594 string favoritesIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? "fas fa-" + Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "fa fa-star"; 5595 5596 5597 <li class="menu-mobile__item logged-in-mobile-item"> 5598 <a href="@myFavoritesPageLink" class="menu-mobile__link menu-mobile__link--highlighted dw-mod"><i class="@favoritesIcon menu-mobile__link-icon"></i> @Translate("My Favorites")</a> 5599 </li> 5600 } 5601 5602 @helper RenderMobileNavigationSavedCardsAction() 5603 { 5604 int signInProfilePageId = GetPageIdByNavigationTag("SignInPage"); 5605 string linkStart = Model.CurrentUser.ID <= 0 ? "/Default.aspx?ID=" + signInProfilePageId + "&RedirectPageId=" : "/Default.aspx?ID="; 5606 int mySavedCardsPageId = GetPageIdByNavigationTag("SavedCards"); 5607 string mySavedCardsPageLink = linkStart + mySavedCardsPageId; 5608 string savedCardsIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SavedCards") != null ? "fas fa-" + Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SavedCards").SelectedValue : "fas fa-credit-card"; 5609 5610 <li class="menu-mobile__item logged-in-mobile-item"> 5611 <a href="@mySavedCardsPageLink" class="menu-mobile__link menu-mobile__link--highlighted dw-mod"><i class="@savedCardsIcon menu-mobile__link-icon"></i> @Translate("My Saved Cards")</a> 5612 </li> 5613 } 5614 5615 @helper RenderMobileNavigationSignOutAction() 5616 { 5617 int pageId = Model.TopPage.ID; 5618 string signOutIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignOutIcon") != null ? "fas fa-" + Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignOutIcon").SelectedValue : "far fa-sign-out-alt"; 5619 5620 <li class="menu-mobile__item logged-in-mobile-item"> 5621 <a class="menu-mobile__link menu-mobile__link--highlighted dw-mod" href="/Admin/Public/ExtranetLogoff.aspx?ID=@pageId" onclick="RememberState.SetCookie('useAnotherAddress', false)"><i class="@signOutIcon menu-mobile__link-icon"></i> @Translate("Sign out")</a> 5622 </li> 5623 } 5624 5625 @helper RenderMobileNavigationLanguagesAction(List<Dynamicweb.Frontend.PageLanguageViewModel> languages) 5626 { 5627 <li class="menu-mobile__item mobile-navigation-language-selector"> 5628 <div class="h3">@Translate("Smartpage:MobileLanguageSelector.Language", "Sprog")</div> 5629 <ul class="menu-mobile u-margin-top"> 5630 @foreach (var lang in languages) 5631 { 5632 var area = Dynamicweb.Services.Areas.GetArea(lang.ID); 5633 string cultureName = Regex.Replace(Dynamicweb.Services.Areas.GetArea(lang.ID).CultureInfo.NativeName, @" ?\(.*?\)", string.Empty); 5634 cultureName = char.ToUpper(cultureName[0]) + cultureName.Substring(1); 5635 string selectedClass = lang.IsCurrent ? "u-underline" : string.Empty; 5636 string url = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl($"Default.aspx?Id={lang.Page.ID}&CurrencyCode={area.EcomCurrencyId}&ActiveLanguageSelection=True"); 5637 5638 string primaryDomain = area.DomainLock; 5639 if (!string.IsNullOrEmpty(primaryDomain)) 5640 { 5641 url = HttpContext.Current.Request.Url.Scheme + "://" + primaryDomain + url; 5642 } 5643 5644 if (url.Contains("/forside")) 5645 { 5646 url = url.Replace("/forside", ""); 5647 } 5648 <li class="u-ta-center"> 5649 <a class="mobile-navigation-language-selector__link @selectedClass" href="@url">@cultureName</a> 5650 </li> 5651 } 5652 </ul> 5653 </li> 5654 } 5655 5656 @helper RenderMobileNavigationCurrenciesAction(List<Currency> currencies) 5657 { 5658 bool languageSelectionFromCookie = Dynamicweb.Environment.CookieManager.GetCookie("ActiveLanguageSelection") != null && Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Environment.CookieManager.GetCookie("ActiveLanguageSelection").Value); 5659 <li class="menu-mobile__item mobile-navigation-currency-selector"> 5660 <div class="h3">@Translate("Smartpage:MobileCurrencySelector.Currency", "Valuta")</div> 5661 <ul class="menu-mobile u-margin-top"> 5662 @foreach (Currency currency in currencies) 5663 { 5664 var pageId = Pageview.Page.ID; 5665 5666 if (!languageSelectionFromCookie) 5667 { 5668 5669 var currencyLanguageMapping = Pageview.AreaSettings.GetItem("Custom").GetItems("CurrencyLanguageMapping")?.FirstOrDefault(m => m.GetRawValueString("Currency") == currency.Code); 5670 if (currencyLanguageMapping != null) 5671 { 5672 var language = Model.Languages.FirstOrDefault(l => l.ID == Dynamicweb.Core.Converter.ToInt32(currencyLanguageMapping.GetRawValueString("Language"))); 5673 5674 if (language != null) 5675 { 5676 pageId = language.Page.ID; 5677 } 5678 } 5679 } 5680 5681 var qs = HttpUtility.ParseQueryString(Dynamicweb.Context.Current.Request.QueryString.ToString()); 5682 qs.Set("ID", Converter.ToString(pageId)); 5683 qs.Set("CurrencyCode", currency.Code); 5684 string url = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?" + qs); 5685 5686 var activeClass = currency.Code == Dynamicweb.Ecommerce.Common.Context.Currency.Code ? "u-underline" : string.Empty; 5687 5688 <li class="u-ta-center"> 5689 <a href="@(url)" class="mobile-navigation-currency-selector__link @(activeClass)">@currency.Code</a> 5690 </li> 5691 5692 } 5693 </ul> 5694 </li> 5695 } 5696 5697 @helper RenderOverlaySearchBar() 5698 { 5699 string searchFeedId = string.Empty; 5700 string searchSecondFeedId = string.Empty; 5701 int groupsFeedId; 5702 string productsSearchId = Converter.ToString(GetPageIdByNavigationTag("ProductSearchFeed")); 5703 int productsPageId = GetPageIdByNavigationTag("ProductsPage"); 5704 string contentSearchPageLink = GetPageIdByNavigationTag("ContentSearchResults") + "&Areaid=" + Model.Area.ID; 5705 string resultPageLink; 5706 string searchPlaceholder; 5707 string searchType = "product-search"; 5708 string searchTemplate; 5709 string searchContentTemplate = ""; 5710 string searchValue = HttpContext.Current.Request.QueryString.Get("Search") ?? ""; 5711 bool showGroups = true; 5712 string beforeSearchTemplate = Pageview.AreaSettings.GetItem("Custom").GetString("MobileBeforeSearchRecommendationsTemplate"); 5713 5714 if (Model.Area.Item.GetItem("Layout").GetList("TopSearch").SelectedValue == "contentSearch") 5715 { 5716 searchFeedId = GetPageIdByNavigationTag("ContentSearchFeed") + "&Areaid=" + Model.Area.ID + "&pagesOnly=true"; 5717 resultPageLink = contentSearchPageLink; 5718 searchPlaceholder = Translate("Search page"); 5719 groupsFeedId = 0; 5720 searchType = "content-search"; 5721 searchTemplate = "SearchPagesTemplate"; 5722 showGroups = false; 5723 } 5724 else if (Model.Area.Item.GetItem("Layout").GetList("TopSearch").SelectedValue == "combinedSearch") 5725 { 5726 searchFeedId = productsSearchId + "&feed=true"; 5727 searchSecondFeedId = GetPageIdByNavigationTag("ContentSearchFeed") + "&Areaid=" + Model.Area.ID + "&pagesOnly=true"; 5728 resultPageLink = Converter.ToString(productsPageId); 5729 searchPlaceholder = Translate("Search products or pages"); 5730 groupsFeedId = GetPageIdByNavigationTag("ProductGroupsFeed"); 5731 searchType = "combined-search"; 5732 searchTemplate = "SearchProductsTemplateWrap"; 5733 searchContentTemplate = "SearchPagesTemplateWrap"; 5734 showGroups = Model.Area.Item.GetItem("Layout").GetBoolean("ShowGroupsSelector"); 5735 } 5736 else 5737 { 5738 resultPageLink = Converter.ToString(productsPageId); 5739 searchFeedId = productsSearchId + "&feed=true"; 5740 groupsFeedId = GetPageIdByNavigationTag("ProductGroupsFeed"); 5741 searchPlaceholder = Translate("Search products"); 5742 searchTemplate = "SearchResultsTypeAheadMobile"; 5743 searchType = "product-search"; 5744 showGroups = Model.Area.Item.GetItem("Layout").GetBoolean("ShowGroupsSelector"); 5745 } 5746 5747 <input type="checkbox" id="MobileSearchTrigger" class="mobile-search-trigger" /> 5748 5749 <div class="main-navigation-mobile typeahead-mobile dw-mod overlay-search"> 5750 <div class="center-container top-container__center-container u-no-padding dw-mod"> 5751 <div class="grid"> 5752 <div class="grid__col-11 u-margin-top u-padding-right"> 5753 <div class="typeahead-mobile__search-field dw-mod u-no-padding-x js-typeahead" id="MobileProductSearch" data-search-feed-id="@searchFeedId" data-search-second-feed-id="@searchSecondFeedId" data-result-page-id="@resultPageLink" data-search-type="@searchType"> 5754 <form class="u-full-width" action="@Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(productsPageId)" id="SearchSubmitForm"> 5755 <input type="text" class="typeahead-autocomplete js-typeahead-autocomplete u-no-margin" disabled /> 5756 <input id="TypeaheadSearchFieldMobile" type="text" class="js-typeahead-search-field u-no-margin typeahead-input-field" data-shop-id="@Pageview.Area.EcomShopId" data-area-id="@Dynamicweb.Core.Converter.ToString(Pageview.AreaID)" placeholder="@HttpUtility.HtmlAttributeEncode(searchPlaceholder)" value="@HttpUtility.HtmlAttributeEncode(searchValue)" /> 5757 <button type="button" class="u-hidden js-typeahead-enter-btn"></button> 5758 <div class="mobile-clear-search-input js-mobile-clear-search-input">@Translate("Smartpage:MobilMenu.clearSearch", "Ryd")</div> 5759 </form> 5760 <span class="typeahead-search-overlay typeahead-search-container js-handlebars-root js-typeahead-search-content dw-mod" id="MobileProductSearchBarContent" data-template="@searchTemplate" data-json-feed="/Default.aspx?ID=@searchFeedId&feedType=productsOnly" data-init-onload="false"></span> 5761 </div> 5762 </div> 5763 <div class="search-overlay-header-close js-search-overlay-close grid__col-1 u-margin-top u-justify-content--center"> 5764 <div class="search-overlay-header-cross"> 5765 <span></span> 5766 <span></span> 5767 </div> 5768 <p class="u-no-margin--bottom">@Translate("Smartpage:MobilMenu.CloseText", "Luk")</p> 5769 </div> 5770 </div> 5771 </div> 5772 </div> 5773 }</text> 5774 } 5775 else 5776 { 5777 <text>@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 5778 5779 @using System 5780 @using System.Web 5781 @using System.Collections.Generic 5782 @using Dynamicweb.Rapido.Blocks.Extensibility 5783 @using Dynamicweb.Rapido.Blocks 5784 @using Smartpage.PhilipsonWine.Ecommerce.CartInformation; 5785 5786 @functions { 5787 BlocksPage headerBlocksPage = BlocksPage.GetBlockPage("Master"); 5788 } 5789 5790 @{ 5791 Block masterTools = new Block() 5792 { 5793 Id = "MasterDesktopTools", 5794 SortId = 10, 5795 Template = RenderDesktopTools(), 5796 SkipRenderBlocksList = true, 5797 BlocksList = new List<Block> 5798 { 5799 new Block { 5800 Id = "MasterDesktopToolsText", 5801 SortId = 10, 5802 Template = RenderDesktopToolsText(), 5803 Design = new Design 5804 { 5805 Size = "auto", 5806 HidePadding = true, 5807 RenderType = RenderType.Column 5808 } 5809 }, 5810 new Block { 5811 Id = "MasterDesktopToolsNavigation", 5812 SortId = 20, 5813 Template = RenderDesktopToolsNavigation(), 5814 Design = new Design 5815 { 5816 Size = "auto-width", 5817 HidePadding = true, 5818 RenderType = RenderType.Column 5819 } 5820 } 5821 } 5822 }; 5823 headerBlocksPage.Add("MasterHeader", masterTools); 5824 5825 Block masterDesktopExtra = new Block() 5826 { 5827 Id = "MasterDesktopExtra", 5828 SortId = 10, 5829 Template = RenderDesktopExtra(), 5830 SkipRenderBlocksList = true 5831 }; 5832 headerBlocksPage.Add("MasterHeader", masterDesktopExtra); 5833 5834 var promoBarSettings = Model.Area.Item.GetItem("Custom").GetItem("PromoBarSettings"); 5835 5836 if (promoBarSettings != null) 5837 { 5838 var promoBarContent = promoBarSettings.GetItems("PromoBarContent"); 5839 5840 if (promoBarContent != null && promoBarContent.Any()) 5841 { 5842 Block promoBar = new Block() 5843 { 5844 Id = "PromoBar", 5845 SortId = 15, 5846 Template = RenderPromoBar(promoBarSettings, promoBarContent), 5847 SkipRenderBlocksList = true 5848 }; 5849 headerBlocksPage.Add("MasterHeader", promoBar); 5850 } 5851 } 5852 5853 if (Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Desktop) 5854 { 5855 Block masterDesktopNavigation = new Block() 5856 { 5857 Id = "MasterDesktopNavigation", 5858 SortId = 20, 5859 Template = RenderDesktopNavigation(), 5860 SkipRenderBlocksList = true 5861 }; 5862 headerBlocksPage.Add("MasterHeader", masterDesktopNavigation); 5863 } 5864 5865 5866 } 5867 5868 @* Include the Blocks for the page *@ 5869 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 5870 @using Dynamicweb.Rapido.Blocks 5871 5872 @{ 5873 bool isSidemenu = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("NavigationMegaMenu") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetRawValueString("NavigationMegaMenu") == "sidemenu" : false; 5874 if (isSidemenu && Pageview.Device.ToString() == "Desktop") 5875 { 5876 Block masterDesktopBurgerMenuBlock = new Block 5877 { 5878 Id = "MasterDesktopBurgerMenu", 5879 SortId = 10, 5880 Template = RenderDesktopBurgerMenu() 5881 }; 5882 5883 BlocksPage.GetBlockPage("Master").Add("MasterDesktopExtra", masterDesktopBurgerMenuBlock); 5884 } 5885 } 5886 5887 @helper RenderDesktopBurgerMenu() 5888 { 5889 if (GetPageIdByNavigationTag("CheckoutPage") > 0 && (Model.ID == GetPageIdByNavigationTag("CartPage") || Model.ID == GetPageIdByNavigationTag("CheckoutPage"))) 5890 { 5891 <a href="/Default.aspx?ID=@GetPageIdByNavigationTag("OffersPage")"> 5892 <div class="grid__col-lg-auto-width grid__col-md-auto-width grid__col-sm-12 grid__col-xs-12 u-no-padding grid--align-self-center dw-mod cart-keep-shopping-icon-container"> 5893 @RenderCartKeepShopping() 5894 <span class="keep-shopping-text">@Translate("Smartpage:Checkout.KeepShopping")</span> 5895 </div> 5896 </a> 5897 } 5898 else 5899 { 5900 <div class="grid__col-lg-auto-width grid__col-md-auto-width grid__col-sm-12 grid__col-xs-12 u-no-padding grid--align-self-center dw-mod desktop-burger-menu js-desktop-burger-menu"> 5901 @RenderDesktopBurgerMenuIcon() 5902 </div> 5903 } 5904 } 5905 5906 @helper RenderDesktopBurgerMenuIcon() 5907 { 5908 <svg class="btn" xmlns="http://www.w3.org/2000/svg" width="95" height="43" viewBox="0 0 95 43"> 5909 <g id="Group_121" data-name="Group 121" transform="translate(0 -3)"> 5910 <g id="Rectangle_3" data-name="Rectangle 3" transform="translate(0 3)" fill="none" stroke="#fff" stroke-width="1"> 5911 <rect width="95" height="43" rx="8" stroke="none" /> 5912 <rect x="0.5" y="0.5" width="94" height="42" rx="7.5" fill="none" /> 5913 </g> 5914 <rect id="Rectangle_5" data-name="Rectangle 5" width="15" height="2" rx="1" transform="translate(14.5 18.8)" fill="#dedede" /> 5915 <rect id="Rectangle_6" data-name="Rectangle 6" width="11" height="2" rx="1" transform="translate(14.5 23.8)" fill="#dedede" /> 5916 <rect id="Rectangle_7" data-name="Rectangle 7" width="15" height="2" rx="1" transform="translate(14.5 28.8)" fill="#dedede" /> 5917 <text id="Menu" transform="translate(38.5 30.5)" fill="#fff" font-size="16" font-family="Mulish-Bold, Mulish" font-weight="700"><tspan x="0" y="0">@Translate("Smartpage:Desktop.Sidemenu.BurgerButton.Text", "Menu")</tspan></text> 5918 </g> 5919 </svg> 5920 } 5921 5922 @helper RenderCartKeepShopping() 5923 { 5924 <svg xmlns="http://www.w3.org/2000/svg" width="16.59" height="13.6" viewBox="0 0 16.59 13.6"> 5925 <g id="Group_6" data-name="Group 6" transform="translate(26.628 88.631) rotate(180)" fill="#c3ad8f"> 5926 <path id="Path_3" data-name="Path 3" d="M11.143,82.939H22.759l-3.732,3.732a1.134,1.134,0,1,0,1.6,1.6L26.3,82.607a1.134,1.134,0,0,0,0-1.6L20.63,75.338a1.134,1.134,0,0,0-1.6,1.6l3.732,3.732H11.143a1.134,1.134,0,0,0,0,2.266Z" /> 5927 </g> 5928 </svg> 5929 } 5930 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 5931 5932 @using System 5933 @using System.Web 5934 @using Dynamicweb.Rapido.Blocks.Extensibility 5935 @using Dynamicweb.Rapido.Blocks 5936 5937 @{ 5938 Block masterDesktopLogo = new Block 5939 { 5940 Id = "MasterDesktopLogo", 5941 SortId = 10, 5942 Template = RenderDesktopLogo(), 5943 Design = new Design 5944 { 5945 Size = "auto-width", 5946 HidePadding = true, 5947 RenderType = RenderType.Column, 5948 CssClass = "grid--align-self-center" 5949 } 5950 }; 5951 5952 BlocksPage.GetBlockPage("Master").Add("MasterHeader", masterDesktopLogo); 5953 } 5954 5955 5956 @helper RenderDesktopLogo() 5957 { 5958 string firstPageId = Model.Area.FirstActivePage.ID.ToString(); 5959 string topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 5960 string alignClass = topLayout == "two-lines-centered" || topLayout == "two-lines" ? "grid--align-self-center" : ""; 5961 alignClass = topLayout == "splitted-center" ? "u-middle" : alignClass; 5962 string logo = Model.Area.Item.GetItem("Layout").GetFile("LogoImage") != null ? Model.Area.Item.GetItem("Layout").GetFile("LogoImage").PathUrlEncoded : "/Files/Images/logo-dynamicweb.png"; 5963 if (Path.GetExtension(logo).ToLower() != ".svg") 5964 { 5965 int logoHeight = Model.Area.Item.GetItem("Layout").GetInt32("LogoHeight"); 5966 logoHeight = logoHeight > 0 && Pageview.Device.ToString() != "Mobile" ? logoHeight : 40; 5967 logo = "/Admin/Public/GetImage.ashx?height=" + Converter.ToString(logoHeight) + "&amp;crop=5&amp;Compression=75&amp;image=" + logo; 5968 } 5969 else 5970 { 5971 logo = HttpUtility.UrlDecode(logo); 5972 } 5973 5974 string isCartPageClass = Model.ID == GetPageIdByNavigationTag("CartPage") || Model.ID == GetPageIdByNavigationTag("CheckoutPage") ? "is-cart-page" : ""; 5975 var url = Dynamicweb.Context.Current.Request.Url.Scheme + "://" + Dynamicweb.Context.Current.Request.Url.Host; 5976 <div class="logo @alignClass dw-mod"> 5977 <a href="@url" class="logo__img dw-mod u-block @isCartPageClass"> 5978 <img class="grid__cell-img logo__img dw-mod @isCartPageClass" src="@logo" alt="@Translate("Logo")" /> 5979 </a> 5980 </div> 5981 } 5982 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 5983 5984 @using System 5985 @using System.Web 5986 @using Dynamicweb.Rapido.Blocks.Extensibility 5987 @using Dynamicweb.Rapido.Blocks 5988 5989 @functions { 5990 string menuType; 5991 } 5992 5993 @{ 5994 menuType = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("NavigationMegaMenu") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetRawValueString("NavigationMegaMenu") : "dropdown"; 5995 Block masterDesktopMenu = new Block 5996 { 5997 Id = "MasterDesktopMenu", 5998 SortId = 10, 5999 Template = RenderDesktopMenu(), 6000 Design = new Design 6001 { 6002 Size = "auto", 6003 HidePadding = true, 6004 RenderType = RenderType.Column 6005 } 6006 }; 6007 6008 if (menuType == "megamenu") 6009 { 6010 masterDesktopMenu.Design.CssClass = "u-reset-position"; 6011 } 6012 6013 if (menuType == "sidemenu") 6014 { 6015 masterDesktopMenu.Design.CssClass = "u-reset-position full-size"; 6016 } 6017 6018 BlocksPage.GetBlockPage("Master").Add("MasterHeader", masterDesktopMenu); 6019 } 6020 6021 @helper RenderDesktopMenu() 6022 { 6023 string topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 6024 string menuAlignment = topLayout == "minimal-right" ? "grid--align-self-end" : ""; 6025 menuAlignment = topLayout == "minimal-center" ? "grid--align-self-center" : topLayout; 6026 string megamenuPromotionImage = Model.Area.Item.GetItem("Layout").GetItem("Header").GetFile("MegamenuPromotionImage") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetFile("MegamenuPromotionImage").PathUrlEncoded : ""; 6027 bool renderPagesInToolBar = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("RenderPagesInToolBar"); 6028 bool showOnlyHeaders = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("ShowOnlyHeaders"); 6029 int startLevel = renderPagesInToolBar ? 1 : 0; 6030 6031 string promotionLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetString("MegamenuPromotionLink"); 6032 6033 <div class="grid__cell u-flex @(menuType == "sidemenu" ? "sidemenu-container js-sidemenu-container" : "") @(menuType == "megamenu" ? "u-reset-position" : "") @menuAlignment"> 6034 @if (Pageview.Page.NavigationTag == "CartPage" && menuType != "sidemenu") 6035 { 6036 <div class="custom__checkout__headerusp grid"> 6037 @RenderUsps("help", Translate("Smartpage:Checkout.Brug for hælp?", "Brug for hælp?"), Translate("Smartpage:Checkout.Tel: 70 22 68 88", "Tel: 70 22 68 88")) 6038 @RenderUsps("Secure", Translate("Smartpage:Checkout.Sikker betaling", "Sikker betaling"), Translate("Smartpage:Checkout.Krypteret betaling", "Krypteret betaling")) 6039 @RenderUsps("delivery", Translate("Smartpage:Checkout.Hurtig levering", "Hurtig levering"), Translate("Smartpage:Checkout.1-2 dages levering", "1-2 dages levering")) 6040 @RenderUsps("tilfredshed", Translate("Smartpage:Checkout.100% tilfredshed!", "100% tilfredshed!"), Translate("Smartpage:Checkout.Du kan nemt sende retur", "Du kan nemt sende retur")) 6041 </div> 6042 } 6043 else 6044 { 6045 var navigationSettings = new Dynamicweb.Frontend.Navigation.NavigationSettings() 6046 { 6047 RootAreaId = 0, 6048 RootPageId = 0, 6049 RootNavigationTag = "main-menu", 6050 StartLevel = 1, 6051 StopLevel = 99, 6052 ExpandMode = Dynamicweb.Frontend.Navigation.ExpandMode.All 6053 }; 6054 6055 var navigationTemplate = "Navigation/SpViewModelNavigation.cshtml"; 6056 6057 @Navigation.RenderNavigation(navigationTemplate, navigationSettings) 6058 } 6059 </div> 6060 } 6061 6062 @helper RenderUsps(string icon, string toptext, string bottomtext) 6063 { 6064 var svg = icon + ".svg"; 6065 6066 <div class="grid__col-12 grid__col-md-3"> 6067 <div class="grid grid--align-center u-justify-content--center border-right"> 6068 <div class="grid__col-2"> 6069 <img src="/Files/Images/SvgIcons/@svg" height="35" width="35" /> 6070 </div> 6071 <div class="grid__col-8"> 6072 <div class="u-block"> 6073 <strong>@toptext</strong> 6074 </div> 6075 <div class="u-block"> 6076 @bottomtext 6077 </div> 6078 </div> 6079 </div> 6080 </div> 6081 } 6082 6083 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 6084 6085 @using System 6086 @using System.Web 6087 @using Dynamicweb.Rapido.Blocks.Extensibility 6088 @using Dynamicweb.Rapido.Blocks 6089 6090 @{ 6091 Block masterDesktopActionsMenu = new Block 6092 { 6093 Id = "MasterDesktopActionsMenu", 6094 SortId = 10, 6095 Template = RenderDesktopActionsMenu(), 6096 Design = new Design 6097 { 6098 CssClass = "u-flex" 6099 }, 6100 SkipRenderBlocksList = true 6101 6102 }; 6103 BlocksPage.GetBlockPage("Master").Add("MasterHeader", masterDesktopActionsMenu); 6104 6105 if (!string.IsNullOrWhiteSpace(Model.Area.Item.GetItem("Layout").GetItem("Header").GetString("HeaderButtonLink"))) 6106 { 6107 Block masterDesktopActionsHeaderButton = new Block 6108 { 6109 Id = "MasterDesktopActionsHeaderButton", 6110 SortId = 60, 6111 Template = RenderHeaderButton() 6112 }; 6113 masterDesktopActionsMenu.Add(masterDesktopActionsHeaderButton); 6114 } 6115 } 6116 6117 @helper RenderDesktopActionsMenu() 6118 { 6119 if (Model.ID != GetPageIdByNavigationTag("CartPage") && Model.ID != GetPageIdByNavigationTag("CheckoutPage")) 6120 { 6121 List<Block> subBlocks = this.headerBlocksPage.GetBlockListById("MasterDesktopActionsMenu").OrderBy(item => item.SortId).ToList(); 6122 6123 <ul class="menu u-flex dw-mod"> 6124 @RenderBlockList(subBlocks) 6125 </ul> 6126 } 6127 else 6128 { 6129 string trustpilotScoreImage = Pageview.AreaSettings.GetItem("Custom").GetRawValueString("TrustpilotScoreImage"); 6130 var headerUSPs = Pageview.AreaSettings.GetItem("Custom").GetItems("HeaderUSP"); 6131 if (!string.IsNullOrEmpty(trustpilotScoreImage) || headerUSPs.Any()) 6132 { 6133 <div class="cart-header-usp-container menu u-flex dw-mod"> 6134 @if (!string.IsNullOrEmpty(trustpilotScoreImage)) 6135 { 6136 <div class="cart-header-usp"> 6137 <span class="cart-header-usp-title">@Translate("Smartpage:Checkout.Anmeldelser", "Anmeldelser")</span> 6138 <img src="@trustpilotScoreImage" /> 6139 </div> 6140 } 6141 @if (headerUSPs.Any()) 6142 { 6143 foreach (var usp in headerUSPs) 6144 { 6145 <div class="cart-header-usp"> 6146 <span class="cart-header-usp-title">@RenderCartHeaderUSPCheckmark() @usp.GetRawValueString("USPTitle")</span> 6147 <span class="cart-header-usp-text">@usp.GetRawValueString("USPDescription")</span> 6148 </div> 6149 } 6150 } 6151 </div> 6152 } 6153 } 6154 } 6155 6156 @helper RenderHeaderButton() 6157 { 6158 string headerButtonText = Model.Area.Item.GetItem("Layout").GetItem("Header").GetString("HeaderButtonText"); 6159 string headerButtonLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetString("HeaderButtonLink"); 6160 string headerButtonType = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("HeaderButtonType") != null ? "btn--" + Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("HeaderButtonType").SelectedName.ToLower() : ""; 6161 6162 <li class="menu__item menu__item--horizontal menu--clean dw-mod"> 6163 <a class="btn @headerButtonType dw-mod u-no-margin u-margin-top u-margin-left" href="@headerButtonLink">@headerButtonText</a> 6164 </li> 6165 } 6166 6167 @helper RenderCartHeaderUSPCheckmark() 6168 { 6169 <svg xmlns="http://www.w3.org/2000/svg" width="12.036" height="8.826" viewBox="0 0 12.036 8.826"> 6170 <g id="Group-2" transform="translate(0 0)"> 6171 <g id="Group_13" data-name="Group 13"> 6172 <g id="Group"> 6173 <g transform="translate(0 0)"> 6174 <path id="Checkmark" d="M.176,9.806a.585.585,0,0,1,0-.837l.851-.837a.609.609,0,0,1,.851,0l2.635,2.591,5.644-5.55a.609.609,0,0,1,.851,0l.851.837a.585.585,0,0,1,0,.837l-6.92,6.806a.609.609,0,0,1-.851,0Z" transform="translate(0 -5)" fill="#c3ad8f" fill-rule="evenodd" /> 6175 </g> 6176 </g> 6177 </g> 6178 </g> 6179 </svg> 6180 } 6181 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 6182 6183 @using System 6184 @using System.Web 6185 @using Dynamicweb.Core; 6186 @using System.Text.RegularExpressions 6187 @using Dynamicweb.Rapido.Blocks.Extensibility 6188 @using Dynamicweb.Rapido.Blocks 6189 6190 @{ 6191 Block masterDesktopActionsMenuLanguageSelector = new Block 6192 { 6193 Id = "MasterDesktopActionsMenuLanguageSelector", 6194 SortId = 40, 6195 Template = RenderLanguageSelector() 6196 }; 6197 6198 @*BlocksPage.GetBlockPage("Master").Add("MasterDesktopActionsMenu", masterDesktopActionsMenuLanguageSelector);*@ 6199 } 6200 6201 @helper RenderLanguageSelector() 6202 { 6203 string topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 6204 string liClasses = topLayout != "normal" ? "menu__item--top-level u-hidden-xxs" : "menu--clean"; 6205 string menuLinkClass = topLayout != "normal" && topLayout != "splitted-center" ? "menu__link menu__link--icon" : "header-menu__link header-menu__link--icon"; 6206 string languageViewType = !string.IsNullOrEmpty(Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("LanguageSelector").SelectedValue) ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("LanguageSelector").SelectedValue.ToLower() : ""; 6207 6208 var languages = Model.Languages.Where(l => Dynamicweb.Services.Areas.GetArea(l.ID).Published).ToList(); 6209 6210 if (languages.Count > 1) 6211 { 6212 <li class="menu__item menu__item--horizontal @liClasses menu__item--icon is-dropdown is-dropdown--no-icon dw-mod"> 6213 <div class="header-menu__link header-menu__link--icon dw-mod"> 6214 <div class="custom__header__icon"> 6215 <div class="custom__header__icon__icon" title="@HttpUtility.HtmlAttributeEncode(Translate("Language"))"> 6216 <i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("LanguageIcon").SelectedValue fa-2_5x"></i> 6217 </div> 6218 <div class="custom__header__icon__text"> 6219 @Translate("Smartpage:LanguageSelector.Language", "Sprog") 6220 </div> 6221 </div> 6222 </div> 6223 <div class="menu menu--dropdown menu--dropdown-right languages-dropdown dw-mod grid__cell"> 6224 @foreach (var lang in languages) 6225 { 6226 var area = Dynamicweb.Content.Services.Areas.GetArea(lang.ID); 6227 var qs = HttpUtility.ParseQueryString(System.Web.HttpContext.Current.Request.QueryString.ToString()); 6228 qs.Set("ID", Converter.ToString(lang.Page.ID)); 6229 qs.Set("AreaID", Converter.ToString(area.ID)); 6230 qs.Set("CurrencyCode", area.EcomCurrencyId); 6231 qs.Set("ActiveLanguageSelection", "True"); 6232 string url = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?" + qs); 6233 string widthClass = "menu__item--fixed-width"; 6234 string langInfo = "<span class=\"flag-icon flag-icon-" + area.EcomCountryCode.ToLower() + " u-margin-right\"></span>" + lang.Name; 6235 string cultureName = Regex.Replace(area.CultureInfo.NativeName, @" ?\(.*?\)", string.Empty); 6236 cultureName = char.ToUpper(cultureName[0]) + cultureName.Substring(1); 6237 string activeClass = Dynamicweb.Ecommerce.Common.Context.LanguageID == area.EcomLanguageId ? "u-bold" : string.Empty; 6238 6239 if (languageViewType == "flag-culture") 6240 { 6241 langInfo = "<span class=\"flag-icon flag-icon-" + area.EcomCountryCode.ToLower() + " \"></span> " + cultureName; 6242 } 6243 6244 if (languageViewType == "flag") 6245 { 6246 langInfo = "<span class=\"flag-icon flag-icon-" + area.EcomCountryCode.ToLower() + " \"></span>"; 6247 widthClass = ""; 6248 } 6249 6250 if (languageViewType == "name") 6251 { 6252 langInfo = lang.Name; 6253 } 6254 6255 if (languageViewType == "culture") 6256 { 6257 langInfo = cultureName; 6258 widthClass = ""; 6259 } 6260 6261 <div class="menu__item dw-mod @widthClass"> 6262 <a href="@url" class="menu-dropdown__link dw-mod @activeClass">@langInfo</a> 6263 </div> 6264 } 6265 </div> 6266 </li> 6267 } 6268 } 6269 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 6270 @using Dynamicweb.Core; 6271 @using Dynamicweb.Rapido.Blocks 6272 @using Smartpage.PhilipsonWine.LoyaltyProgram.Helpers 6273 6274 @{ 6275 Block masterDesktopActionsMenuSignIn = new Block 6276 { 6277 Id = "MasterDesktopActionsMenuSignIn", 6278 SortId = 20, 6279 Template = RenderSignIn() 6280 }; 6281 6282 BlocksPage.GetBlockPage("Master").Add("MasterDesktopActionsMenu", masterDesktopActionsMenuSignIn); 6283 } 6284 6285 @helper RenderSignIn() 6286 { 6287 bool navigationItemsHideSignIn = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("HideSignIn"); 6288 string userInitials = ""; 6289 int pageId = Model.Area.FirstPage.ID; 6290 int createAccountPageId = GetPageIdByNavigationTag("CreateAccount"); 6291 int myDashboardPageId = GetPageIdByNavigationTag("CustomerDashboard"); 6292 int myProfilePageId = GetPageIdByNavigationTag("CustomerProfile"); 6293 int myOrdersPageId = GetPageIdByNavigationTag("CustomerOrders"); 6294 int myFavoritesPageId = GetPageIdByNavigationTag("CustomerFavorites"); 6295 int mySavedCardsPageId = GetPageIdByNavigationTag("SavedCards"); 6296 int myOrderDraftsPageId = GetPageIdByNavigationTag("OrderDraft"); 6297 int customerStockPageId = GetPageIdByNavigationTag("CustomerStockPage"); 6298 int signInProfilePageId = GetPageIdByNavigationTag("SignInPage"); 6299 int mySubscriptionsPageId = GetPageIdByNavigationTag("MySubscriptionsPage"); 6300 bool hideCreateAccountLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideCreateAccount"); 6301 bool hideMyProfileLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideProfile"); 6302 bool hideMyOrdersLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideOrders"); 6303 bool hideMySavedCardsLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideSavedCards"); 6304 bool hideMyOrderDraftsLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideOrderDrafts"); 6305 bool hideMyFavoritesLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideFavorites"); 6306 bool hideForgotPasswordLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideForgotPasswordLink"); 6307 // Should check on the user if the user has customer stock 6308 bool hideCustomerStock = false; 6309 6310 string linkStart = "/Default.aspx?ID="; 6311 if (Model.CurrentUser.ID <= 0) 6312 { 6313 linkStart += signInProfilePageId + "&RedirectPageId="; 6314 } 6315 6316 string forgotPasswordPageLink = "/Default.aspx?ID=" + signInProfilePageId + "&LoginAction=Recovery"; 6317 string myDashboardPageLink = linkStart + myDashboardPageId; 6318 string myProfilePageLink = linkStart + myProfilePageId; 6319 string myOrdersPageLink = linkStart + myOrdersPageId; 6320 string myFavoritesPageLink = linkStart + myFavoritesPageId; 6321 string mySavedCardsPageLink = linkStart + mySavedCardsPageId; 6322 string myOrderDraftsLink = linkStart + myOrderDraftsPageId; 6323 string customerStockLink = linkStart + customerStockPageId; 6324 string mySubscriptionsLink = linkStart + mySubscriptionsPageId; 6325 6326 string profileIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignInProfileIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignInProfileIcon").SelectedValue : "fa fa-user"; 6327 string favoritesIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? "fas fa-" + Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "fa fa-star"; 6328 string orderDraftsIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("DraftIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("DraftIcon").SelectedValue : "fa fa-clipboard"; 6329 6330 if (Model.CurrentUser.ID != 0) 6331 { 6332 userInitials = Dynamicweb.Rapido.Services.User.GetInitials(Model.CurrentUser.Name, Model.CurrentUser.FirstName, Model.CurrentUser.LastName, Model.CurrentUser.Email, Model.CurrentUser.UserName); 6333 } 6334 6335 bool businessContactImpersonation = false; 6336 6337 if (Model.CurrentSecondaryUser != null && Model.CurrentSecondaryUser.ID > 0) 6338 { 6339 businessContactImpersonation = Converter.ToBoolean(Model.CurrentSecondaryUser.CustomFields.Values.FirstOrDefault(x => x.SystemName == "AccessUser_SpBcImpersonator")?.Value); 6340 } 6341 6342 if (!navigationItemsHideSignIn) 6343 { 6344 string topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 6345 string liClasses = topLayout != "normal" ? "menu__item--top-level u-hidden-xxs" : "menu__item--clean"; 6346 string menuLinkClass = topLayout != "normal" && topLayout != "splitted-center" ? "menu__link menu__link--icon" : "header-menu__link header-menu__link--icon"; 6347 bool hasPricePook = false; 6348 6349 <li class="menu__item menu__item--horizontal menu__item menu__item--icon @liClasses is-dropdown is-dropdown--no-icon dw-mod"> 6350 <div class="@menuLinkClass dw-mod"> 6351 @if (Model.CurrentUser.ID <= 0) 6352 { 6353 6354 <div class="custom__header__icon"> 6355 <div class="custom__header__icon__icon"> 6356 <svg width="23px" height="40px" viewBox="0 0 23 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 6357 <title>Group 4</title> 6358 <g id="Header" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 6359 <g transform="translate(-1392.000000, -66.000000)" fill="#FFFFFF" id="Header---2022---Dec"> 6360 <g transform="translate(-1.000000, 0.000000)"> 6361 <g id="Profil" transform="translate(1357.000000, 66.194216)"> 6362 <g id="Group-4" transform="translate(36.000000, 0.000000)"> 6363 <path d="M21.9976173,23.9160939 C22.7572186,23.7577881 23.209611,22.9629324 22.8321614,22.2850013 C22.0000535,20.7904769 20.6891658,19.4771996 19.0122125,18.4763775 C16.8524643,17.187417 14.2062291,16.4887568 11.4839257,16.4887568 C8.76162096,16.4887568 6.11538574,17.1874142 3.95563616,18.476372 C2.27868151,19.4771941 0.967790992,20.7904714 0.135684508,22.2849958 C-0.241767867,22.9629242 0.210623159,23.7577826 0.970225832,23.916087 L0.970225832,23.916087 C7.90485829,25.3613018 15.0629821,25.3613046 21.9976173,23.9160939 L21.9976173,23.9160939 Z" id="Fill-936"></path> 6364 <path d="M18.354274,6.87031532 C18.354274,10.664686 15.2783294,13.7406306 11.4839587,13.7406306 C7.68958795,13.7406306 4.61364336,10.664686 4.61364336,6.87031532 C4.61364336,3.0759446 7.68958795,0 11.4839587,0 C15.2783294,0 18.354274,3.0759446 18.354274,6.87031532 Z" id="Fill-937"></path> 6365 </g> 6366 </g> 6367 </g> 6368 </g> 6369 </g> 6370 </svg> 6371 </div> 6372 <div class="custom__header__icon__text"> 6373 @Translate("Smartpage:Header.IconsText.LoginOpret", "Log ind") 6374 <div class="custom__header__icon__text__subtext">@Translate("Smartpage:Header.IconsText.LoginOpret.SubText", "Opret og få bonus")</div> 6375 </div> 6376 </div> 6377 } 6378 else 6379 { 6380 6381 string bonusFormatted = ""; 6382 6383 double bonus = Dynamicweb.Ecommerce.Services.Loyalty.GetPointsBalance(Dynamicweb.Security.UserManagement.User.GetCurrentFrontendUser()); 6384 6385 if (Dynamicweb.Core.Converter.ToDouble(bonus) > 0.0) 6386 { 6387 bonusFormatted = Dynamicweb.Ecommerce.Services.Currencies.Format(Dynamicweb.Ecommerce.Common.Context.Currency, bonus); 6388 } 6389 6390 <a @(!businessContactImpersonation ? "href=\"" + myDashboardPageLink + "\"" : string.Empty)> 6391 <div class="custom__header__icon"> 6392 <div class="custom__header__icon__icon"> 6393 <svg width="23px" height="40px" viewBox="0 0 23 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 6394 <title></title> 6395 <g id="Header" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 6396 <g transform="translate(-1392.000000, -66.000000)" fill="#FFFFFF" id="Header---2022---Dec"> 6397 <g transform="translate(-1.000000, 0.000000)"> 6398 <g id="Profil" transform="translate(1357.000000, 66.194216)"> 6399 <g id="Group-4" transform="translate(36.000000, 0.000000)"> 6400 <path d="M21.9976173,23.9160939 C22.7572186,23.7577881 23.209611,22.9629324 22.8321614,22.2850013 C22.0000535,20.7904769 20.6891658,19.4771996 19.0122125,18.4763775 C16.8524643,17.187417 14.2062291,16.4887568 11.4839257,16.4887568 C8.76162096,16.4887568 6.11538574,17.1874142 3.95563616,18.476372 C2.27868151,19.4771941 0.967790992,20.7904714 0.135684508,22.2849958 C-0.241767867,22.9629242 0.210623159,23.7577826 0.970225832,23.916087 L0.970225832,23.916087 C7.90485829,25.3613018 15.0629821,25.3613046 21.9976173,23.9160939 L21.9976173,23.9160939 Z" id="Fill-936"></path> 6401 <path d="M18.354274,6.87031532 C18.354274,10.664686 15.2783294,13.7406306 11.4839587,13.7406306 C7.68958795,13.7406306 4.61364336,10.664686 4.61364336,6.87031532 C4.61364336,3.0759446 7.68958795,0 11.4839587,0 C15.2783294,0 18.354274,3.0759446 18.354274,6.87031532 Z" id="Fill-937"></path> 6402 </g> 6403 </g> 6404 </g> 6405 </g> 6406 </g> 6407 </svg> 6408 </div> 6409 <div class="custom__header__icon__text"> 6410 @{ 6411 6412 6413 string name = Translate("Smartpage:Header.IconsText.MinProfil", "Min profil"); 6414 int maxLength = 20; 6415 if (businessContactImpersonation) 6416 { 6417 if (Model.CurrentSecondaryUser.Name.Count() > maxLength) 6418 { 6419 name = Model.CurrentSecondaryUser.Name.Substring(0, maxLength - 3) + "..."; 6420 } 6421 else 6422 { 6423 name = Model.CurrentSecondaryUser.Name; 6424 } 6425 } 6426 else if (!string.IsNullOrWhiteSpace(Model.CurrentUser.FirstName)) 6427 { 6428 name = Model.CurrentUser.FirstName; 6429 } 6430 else if (!string.IsNullOrWhiteSpace(Model.CurrentUser.Name)) 6431 { 6432 if (Model.CurrentUser.Name.Count() > maxLength) 6433 { 6434 name = Model.CurrentUser.Name.Substring(0, maxLength - 3) + "..."; 6435 } 6436 else 6437 { 6438 name = Model.CurrentUser.Name; 6439 } 6440 } 6441 6442 @name 6443 if (!string.IsNullOrEmpty(bonusFormatted)) 6444 { 6445 var user = Dynamicweb.Security.UserManagement.User.GetCurrentFrontendUser(); 6446 <div class="custom__header__icon__text__subtext">@string.Format(Translate("Smartpage:SignInActions.Bonus", "Din {0}: {1}"), Helper.GetWelcomeBonus(user) != null ? "velkomstrabat" : "bonus", bonusFormatted)</div> 6447 } 6448 } 6449 </div> 6450 </div> 6451 </a> 6452 } 6453 </div> 6454 <div class="menu menu--dropdown menu--dropdown-right menu--sign-in grid__cell dw-mod"> 6455 <ul class="list list--clean dw-mod"> 6456 @if (Model.CurrentUser.ID <= 0) 6457 { 6458 <li> 6459 <label for="SignInModalTrigger" class="btn btn--primary btn--full u-no-margin sign-in-modal-trigger-button dw-mod js-sign-in-modal-trigger">@Translate("Sign in")</label> 6460 </li> 6461 6462 if (!hideCreateAccountLink) 6463 { 6464 @RenderListItem("/default.aspx?ID=" + createAccountPageId, Translate("Create account")); 6465 } 6466 if (!hideForgotPasswordLink) 6467 { 6468 @RenderListItem(forgotPasswordPageLink, Translate("Forgot your password?")) 6469 } 6470 if (!hideMyProfileLink || !hideMyOrdersLink || !hideMyFavoritesLink || !hideMySavedCardsLink || !hideCustomerStock) 6471 { 6472 @RenderSeparator() 6473 } 6474 } 6475 @if (!hideMyProfileLink && !businessContactImpersonation) 6476 { 6477 @RenderListItem(myProfilePageLink, Translate("My Profile"), profileIcon) 6478 } 6479 6480 @if (!businessContactImpersonation) 6481 { 6482 @RenderListItem(myDashboardPageLink, Translate("Smartpage:SignInActions.Dashboard", "Mit overblik"), "fas fa-th") 6483 } 6484 6485 @if (!hideMyOrdersLink && !businessContactImpersonation) 6486 { 6487 @RenderListItem(myOrdersPageLink, Translate("My Orders"), "fas fa-list") 6488 } 6489 @if (!hideMyFavoritesLink && !businessContactImpersonation) 6490 { 6491 @RenderListItem(myFavoritesPageLink, Translate("My Favorites"), favoritesIcon) 6492 } 6493 @if (!hideMySavedCardsLink && !businessContactImpersonation) 6494 { 6495 @RenderListItem(mySavedCardsPageLink, Translate("My Saved cards"), "fas fa-credit-card") 6496 } 6497 @if (!hideCustomerStock && !businessContactImpersonation) 6498 { 6499 @RenderListItem(customerStockLink, Translate("Smartpage:SignInActions.CustomerStock", "Mit kundelager"), "fal fa-clipboard-list") 6500 } 6501 6502 @if (Model.CurrentUser.ID > 0) 6503 { 6504 var priceBookList = Dynamicweb.Ecommerce.CustomerCenter.CustomerProductList.GetListByCustomerId(Converter.ToInt32(Model.CurrentUser.ID))?.FirstOrDefault(l => l.Type == "PriceBookList"); 6505 if (priceBookList != null) 6506 { 6507 string link = $"/Default.aspx?Id={GetPageIdByNavigationTag("FavoriteProductsPage")}&ListID={priceBookList.ID}&ListName={priceBookList.Name}"; 6508 @RenderListItem(link, Translate("Smartpage:SignInActions.PriceBookList", "Prisbog"), "fal fa-dollar-sign") 6509 6510 hasPricePook = true; 6511 } 6512 } 6513 6514 @if (mySubscriptionsPageId != 0 && !businessContactImpersonation) 6515 { 6516 @RenderListItem(mySubscriptionsLink, Translate("Smartpage:SignInActions.MySubscriptions", "Mine abonnementer"), "fal fa-clipboard-list") 6517 } 6518 6519 @if (!hideMyOrderDraftsLink && !businessContactImpersonation) 6520 { 6521 @RenderListItem(myOrderDraftsLink, Translate("My Order drafts"), orderDraftsIcon) 6522 } 6523 @if (Model.CurrentUser.ID > 0) 6524 { 6525 if ((!hideMyProfileLink || !hideMyOrdersLink || !hideMyFavoritesLink || !hideMySavedCardsLink) && (!businessContactImpersonation || hasPricePook)) 6526 { 6527 @RenderSeparator() 6528 } 6529 6530 //Check if impersonation is on 6531 if (Model.CurrentSecondaryUser != null && Model.CurrentSecondaryUser.ID > 0) 6532 { 6533 <li> 6534 <div class="list__link dw-mod" onclick="document.getElementById('StopImpersonationModalTrigger').checked = true;"> 6535 @Translate("Sign out") 6536 </div> 6537 </li> 6538 } 6539 else 6540 { 6541 @RenderListItem("/Admin/Public/ExtranetLogoff.aspx?ID=" + pageId, Translate("Sign out")) 6542 } 6543 } 6544 </ul> 6545 </div> 6546 </li> 6547 } 6548 } 6549 6550 @helper RenderListItem(string link, string text, string icon = null) 6551 { 6552 <li> 6553 <a href="@link" class="list__link dw-mod" onclick="RememberState.SetCookie('useAnotherAddress', false)"> 6554 @if (!string.IsNullOrEmpty(icon)) 6555 {<i class="@icon u-margin-right"></i>}@text 6556 </a> 6557 </li> 6558 } 6559 6560 @helper RenderSeparator() 6561 { 6562 <li class="list__seperator dw-mod"></li> 6563 } 6564 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 6565 6566 @using System 6567 @using System.Web 6568 @using Dynamicweb.Rapido.Blocks.Extensibility 6569 @using Dynamicweb.Rapido.Blocks 6570 6571 @{ 6572 bool hideMyFavoritesLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("HideFavorites"); 6573 6574 Block masterDesktopActionsMenuFavorites = new Block 6575 { 6576 Id = "MasterDesktopActionsMenuFavorites", 6577 SortId = 30, 6578 Template = RenderFavorites() 6579 }; 6580 6581 if (!hideMyFavoritesLink && Model.CurrentUser.ID > 0) 6582 { 6583 BlocksPage.GetBlockPage("Master").Add("MasterDesktopActionsMenu", masterDesktopActionsMenuFavorites); 6584 } 6585 } 6586 6587 @helper RenderFavorites() 6588 { 6589 int myFavoritesPageId = GetPageIdByNavigationTag("CustomerFavorites"); 6590 string myFavoritesPageLink = "/Default.aspx?ID=" + myFavoritesPageId; 6591 6592 string topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 6593 string liClasses = topLayout != "normal" && topLayout != "splitted-center" ? "menu__item--top-level u-hidden-xxs" : "menu--clean"; 6594 string menuLinkClass = topLayout != "normal" && topLayout != "splitted-center" ? "menu__link menu__link--icon" : "header-menu__link header-menu__link--icon"; 6595 6596 <li class="menu__item menu__item--horizontal @liClasses menu__item--icon dw-mod"> 6597 <a href="@myFavoritesPageLink" class="@menuLinkClass dw-mod" title="@Translate("Favorites")"> 6598 <i class="fas fa-@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue fa-1_5x"></i> 6599 </a> 6600 </li> 6601 } 6602 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 6603 6604 @using System 6605 @using System.Web 6606 @using Dynamicweb.Rapido.Blocks.Extensibility 6607 @using Dynamicweb.Rapido.Blocks 6608 @using Dynamicweb.Rapido.Services 6609 @using Smartpage.PhilipsonWine.Ecommerce.CartInformation; 6610 @using Smartpage.PhilipsonWine.Freight.Helpers; 6611 6612 @functions{ 6613 public Dynamicweb.Security.UserManagement.User GetCurrentUser() => Dynamicweb.Security.UserManagement.User.GetCurrentFrontendUser(); 6614 public bool GetActivateFreightMeter() => Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetBoolean("ActivateFreightMeter"); 6615 public double GetFreeShippingLimit() => Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetDouble("FreeShippingLimit"); 6616 } 6617 6618 @{ 6619 bool hideCart = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("HideCart"); 6620 string miniCartLayout = Model.Area.Item.GetItem("Ecommerce").GetItem("MiniCart").GetList("Layout") != null ? Model.Area.Item.GetItem("Ecommerce").GetItem("MiniCart").GetList("Layout").SelectedValue : "dropdown"; 6621 6622 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed() && !hideCart) 6623 { 6624 Block masterDesktopActionsMenuMiniCart = new Block 6625 { 6626 Id = "MasterDesktopActionsMenuMiniCart", 6627 SortId = 60, 6628 Template = RenderMiniCart(miniCartLayout == "dropdown"), 6629 SkipRenderBlocksList = true, 6630 BlocksList = new List<Block>() 6631 }; 6632 6633 Block miniCartCounterScriptTemplate = new Block 6634 { 6635 Id = "MiniCartCounterScriptTemplate", 6636 Template = RenderMiniCartCounterContent() 6637 }; 6638 6639 Block miniCartFreightMeterScriptTemplate = new Block 6640 { 6641 Id = "MiniCartFreightMeterScriptTemplate", 6642 Template = RenderMiniCartFreightMeterScript() 6643 }; 6644 6645 //dropdown layout is default 6646 RazorEngine.Templating.TemplateWriter layoutTemplate; 6647 RazorEngine.Templating.TemplateWriter miniCartTriggerTemplate; 6648 switch (miniCartLayout) 6649 { 6650 case "dropdown": 6651 layoutTemplate = RenderMiniCartDropdownLayout(); 6652 miniCartTriggerTemplate = RenderMiniCartTriggerLink(); 6653 break; 6654 case "panel": 6655 layoutTemplate = RenderMiniCartPanelLayout(); 6656 miniCartTriggerTemplate = RenderMiniCartTriggerLabel(); 6657 break; 6658 case "modal": 6659 layoutTemplate = RenderMiniCartModalLayout(); 6660 miniCartTriggerTemplate = RenderMiniCartTriggerLabel(); 6661 break; 6662 case "none": 6663 default: 6664 layoutTemplate = RenderMiniCartDropdownLayout(); 6665 miniCartTriggerTemplate = RenderMiniCartTriggerLink(); 6666 break; 6667 } 6668 6669 masterDesktopActionsMenuMiniCart.BlocksList.Add(new Block 6670 { 6671 Id = "MiniCartTrigger", 6672 Template = miniCartTriggerTemplate 6673 }); 6674 6675 if (Pageview.Device.ToString() != "Mobile") 6676 { 6677 masterDesktopActionsMenuMiniCart.BlocksList.Add(new Block 6678 { 6679 Id = "MiniCartLayout", 6680 Template = layoutTemplate 6681 }); 6682 } 6683 6684 BlocksPage.GetBlockPage("Master").Add("MasterDesktopActionsMenu", masterDesktopActionsMenuMiniCart); 6685 BlocksPage.GetBlockPage("Master").Add("MasterBottomSnippets", miniCartCounterScriptTemplate); 6686 if (GetActivateFreightMeter()) 6687 { 6688 BlocksPage.GetBlockPage("Master").Add("MasterBottomSnippets", miniCartFreightMeterScriptTemplate); 6689 } 6690 } 6691 6692 if (hideCart && Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 6693 { 6694 BlocksPage.GetBlockPage("Master").Add("MasterBottomSnippets", new Block 6695 { 6696 Id = "CartInitialization" 6697 }); 6698 } 6699 } 6700 6701 @helper RenderMiniCart(bool hasMouseEnterEvent) 6702 { 6703 List<Block> subBlocks = this.masterPage.GetBlockListById("MasterDesktopActionsMenuMiniCart").OrderBy(item => item.SortId).ToList(); 6704 string topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 6705 string liClasses = topLayout != "normal" ? "menu__item--top-level" : "menu--clean"; 6706 int miniCartFeedPageId = GetPageIdByNavigationTag("MiniCartFeed"); 6707 string mouseEvent = ""; 6708 string id = "MiniCart"; 6709 if (hasMouseEnterEvent) 6710 { 6711 mouseEvent = "onmouseenter=\"Cart.UpdateMiniCart('miniCartTrigger', 'miniCart', 'cartCounter', '/Default.aspx?ID=" + miniCartFeedPageId + "&feedType=MiniCart')\""; 6712 id = "miniCartTrigger"; 6713 } 6714 <li class="menu__item menu__item--horizontal menu__item--icon @liClasses dw-mod" id="@id" @mouseEvent> 6715 @RenderBlockList(subBlocks) 6716 </li> 6717 } 6718 6719 @helper RenderMiniCartTriggerLabel() 6720 { 6721 int cartPageId = GetPageIdByNavigationTag("CartPage"); 6722 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fa fa-cart"; 6723 string topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 6724 string menuLinkClass = topLayout != "normal" && topLayout != "splitted-center" ? "menu__link menu__link--icon" : "header-menu__link header-menu__link--icon"; 6725 int miniCartFeedPageId = GetPageIdByNavigationTag("MiniCartFeed"); 6726 6727 <a class="@menuLinkClass dw-mod js-mini-cart-button u-flex u-flex--column mini-cart" href="/Default.aspx?ID=@cartPageId" title="@HttpUtility.HtmlAttributeEncode(Translate("Cart"))"> 6728 <div class="custom__header__icon mini-cart"> 6729 <div class="custom__header__icon__icon cart" title="@Translate("Cart")"> 6730 <object data="/Files/Images/SvgIcons/basket.svg" type="image/svg+xml"> 6731 <span>Your browser doesn't support SVG images</span> 6732 </object> 6733 </div> 6734 @RenderMiniCartCounter(miniCartFeedPageId) 6735 </div> 6736 @if (GetActivateFreightMeter()) 6737 { 6738 @RenderMiniCartFreightMeter(miniCartFeedPageId) 6739 } 6740 </a> 6741 } 6742 6743 @helper RenderMiniCartTriggerLink() 6744 { 6745 int cartPageId = GetPageIdByNavigationTag("CartPage"); 6746 string cartIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue : "fa fa-cart"; 6747 string topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 6748 string menuLinkClass = topLayout != "normal" && topLayout != "splitted-center" ? "menu__link menu__link--icon" : "header-menu__link header-menu__link--icon"; 6749 int miniCartFeedPageId = GetPageIdByNavigationTag("MiniCartFeed"); 6750 6751 <a href="/Default.aspx?ID=@cartPageId" class="@menuLinkClass menu__item--icon dw-mod js-mini-cart-button" title="@HttpUtility.HtmlAttributeEncode(Translate("Cart"))"> 6752 <div class="custom__header__icon"> 6753 <div class="custom__header__icon__icon" title="@HttpUtility.HtmlAttributeEncode(Translate("Cart"))"> 6754 <object data="/Files/Images/SvgIcons/basket.svg" type="image/svg+xml"> 6755 <span>Your browser doesn't support SVG images</span> 6756 </object> 6757 </div> 6758 @RenderMiniCartCounter(miniCartFeedPageId) 6759 </div> 6760 </a> 6761 } 6762 6763 @helper RenderMiniCartCounter(int miniCartFeedPageId) 6764 { 6765 double cartProductsCount = 0; 6766 bool cartContainsSubscriptionOrderLine = false; 6767 6768 if (Model != null && Model.Cart != null && Model.Cart.CartOrderlines != null) 6769 { 6770 CartInformation cartInformation = new CartInformation(Model.Cart); 6771 6772 cartProductsCount = cartInformation.OrderLineCount; 6773 cartContainsSubscriptionOrderLine = cartInformation.ContainsSubscriptionOrderLine; 6774 } 6775 6776 string counterPosition = Model.Area.Item.GetItem("Ecommerce").GetItem("MiniCart").GetList("CounterPosition") != null ? Model.Area.Item.GetItem("Ecommerce").GetItem("MiniCart").GetList("CounterPosition").SelectedValue : "right"; 6777 bool showPrice = Model.Area.Item.GetItem("Ecommerce").GetItem("MiniCart").GetBoolean("ShowPrice"); 6778 string cartProductsTotalPrice = (Model.Cart.TotalPrice != null) ? Model.Cart.TotalPrice.Price.Value.ToString("N2") : "0,00 "; 6779 double freeFee = GetFreeShippingLimit(); 6780 double amountToFreeFreight = (Model.Cart.TotalPriceWithoutFees != null) ? freeFee - Model.Cart.TotalPriceWithoutFees.PriceWithVat.Value : freeFee; 6781 string amountToFreeFreightFormatted = amountToFreeFreight.ToString("N2"); 6782 string currencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Symbol; 6783 bool isFreeFreight = amountToFreeFreight <= 0 || cartContainsSubscriptionOrderLine || UserHelper.IsUserWithFreeFreight(GetCurrentUser()); 6784 6785 <div class="js-handlebars-root js-mini-cart-counter u-flex u-justify-content--center u-align-end u-flex--column" id="cartCounter" data-template="MiniCartCounterContent" data-json-feed="/Default.aspx?ID=@miniCartFeedPageId&feedType=Counter" data-init-onload="false"> 6786 <div class="custom__header__icon__counter"> 6787 <div class="mini-cart__counter dw-mod"> 6788 <span class="js-mini-cart-counter-content" data-count="@cartProductsCount"> 6789 @cartProductsCount 6790 </span> 6791 </div> 6792 </div> 6793 <div> 6794 <div class="u-flex u-flex--row"> 6795 <span class="custom__header__icon__text price u-flex"> 6796 @cartProductsTotalPrice 6797 </span> 6798 <span class="custom__header__icon__text currency u-flex">@currencyCode</span> 6799 </div> 6800 @if (GetActivateFreightMeter()) 6801 { 6802 <div class="custom__header__icon__freight-text"> 6803 @if (isFreeFreight) 6804 { 6805 <span class="custom__header__icon__freight-text__freight-bold success u-flex">@Translate("Smartpage:MiniCart.YouHaveFreeFreight", "Du har fri fragt!")</span> 6806 } 6807 else 6808 { 6809 @amountToFreeFreightFormatted @currencyCode @Translate("Smartpage:MiniCart.From", " fra") 6810 <span class="custom__header__icon__freight-text__freight-bold">@Translate("Smartpage:MiniCart.FreeFreight", "fri fragt")</span> 6811 } 6812 </div> 6813 } 6814 6815 </div> 6816 </div> 6817 6818 } 6819 6820 @helper RenderMiniCartFreightMeter(int miniCartFeedPageId) 6821 { 6822 string widthCss = "width: 0%"; 6823 6824 if (UserHelper.IsUserWithFreeFreight(GetCurrentUser())) 6825 { 6826 widthCss = $"width: 100%"; 6827 } 6828 else if (Dynamicweb.Ecommerce.Common.Context.Cart != null) 6829 { 6830 CartInformation cartInformation = new CartInformation(Model.Cart); 6831 if (cartInformation.ContainsSubscriptionOrderLine) 6832 { 6833 widthCss = $"width: 100%"; 6834 } 6835 else 6836 { 6837 double freeFee = GetFreeShippingLimit(); 6838 double percentageFreeFreight = 100 - (((freeFee - Model.Cart.TotalPriceWithoutFees.PriceWithVat.Value) / freeFee) * 100); 6839 percentageFreeFreight = Math.Ceiling(percentageFreeFreight); 6840 if (percentageFreeFreight > 100) 6841 { 6842 percentageFreeFreight = 100; 6843 } 6844 widthCss = $"width: {percentageFreeFreight}%"; 6845 } 6846 } 6847 6848 <div class="js-handlebars-root " id="miniCartFreightMeter" data-template="MiniCartFreightMeter" data-json-feed="/Default.aspx?ID=@miniCartFeedPageId" data-init-onload="false" data-preloader="none"> 6849 <div class="progress-bar-container u-margin-left"> 6850 <div class="progress-bar-indicator" style="@widthCss"></div> 6851 </div> 6852 </div> 6853 } 6854 6855 @helper RenderMiniCartFreightMeterScript() 6856 { 6857 <script id="MiniCartFreightMeter" type="text/x-template"> 6858 {{#.}} 6859 <div class="progress-bar-container u-margin-left"> 6860 <div class="progress-bar-indicator" style="width:{{percentageFreeFreight}}%"></div> 6861 </div> 6862 {{/.}} 6863 </script> 6864 } 6865 6866 @helper RenderMiniCartCounterContent() 6867 { 6868 <script id="MiniCartCounterContent" type="text/x-template"> 6869 {{#.}} 6870 <div class="custom__header__icon__counter"> 6871 <div class="mini-cart__counter dw-mod"> 6872 <span class="js-mini-cart-counter-content" data-count="{{numberofproducts}}"> 6873 {{numberofproducts}} 6874 </span> 6875 </div> 6876 </div> 6877 <div> 6878 <div class="u-flex u-flex--row"> 6879 <span class="custom__header__icon__text price u-flex"> 6880 {{totalpriceCleanFormatted}} 6881 </span> 6882 <span class="custom__header__icon__text currency u-flex">{{currencyCode}}</span> 6883 </div> 6884 @if (GetActivateFreightMeter()) 6885 { 6886 <div class="custom__header__icon__freight-text"> 6887 {{#if isFreeFreight}} 6888 <span class="custom__header__icon__freight-text__freight-bold success u-flex">@Translate("Smartpage:MiniCart.YouHaveFreeFreight", "Du har fri fragt!")</span> 6889 {{else}} 6890 {{amountToFreeFreightFormatted}} {{currencyCode}} @Translate("Smartpage:MiniCart.From", " fra") 6891 <span class="custom__header__icon__freight-text__freight-bold">@Translate("Smartpage:MiniCart.FreeFreight", "fri fragt")</span> 6892 {{/if}} 6893 </div> 6894 } 6895 </div> 6896 {{/.}} 6897 </script> 6898 } 6899 6900 6901 @helper RenderMiniCartDropdownLayout() 6902 { 6903 int miniCartFeedPageId = GetPageIdByNavigationTag("MiniCartFeed"); 6904 string cartPageLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("CartPage"); 6905 6906 <div class="mini-cart mini-cart-dropdown js-mini-cart grid__cell dw-mod" id="miniCart" data-cart-id="@miniCartFeedPageId" data-show-type="dropdown" data-cart-page-link="@cartPageLink"> 6907 <div class="mini-cart-dropdown__inner dw-mod"> 6908 <h3 class="u-ta-center dw-mod">@Translate("Shopping cart")</h3> 6909 <div class="mini-cart-dropdown__body u-flex dw-mod"> 6910 <div class="js-handlebars-root u-flex grid--direction-column u-full-width dw-mod" id="miniCartContent" data-template="MiniCartContent" data-json-feed="/Default.aspx?ID=@miniCartFeedPageId&feedType=MiniCart" data-init-onload="false"></div> 6911 </div> 6912 </div> 6913 </div> 6914 } 6915 6916 @helper RenderMiniCartPanelLayout() 6917 { 6918 int miniCartFeedPageId = GetPageIdByNavigationTag("MiniCartFeed"); 6919 string cartPageLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("CartPage"); 6920 6921 <div class="mini-cart grid__cell dw-mod"> 6922 <input type="checkbox" id="miniCartTrigger" class="panel-trigger" /> 6923 <div class="panel panel--right panel--with-close-btn dw-mod js-mini-cart" id="miniCart" data-cart-id="@miniCartFeedPageId" data-show-type="block" data-cart-page-link="@cartPageLink"> 6924 <label for="miniCartTrigger" class="panel__close-btn" title="@Translate("Close panel")"><i class="fas fa-times"></i></label> 6925 <div class="panel__content u-full-width dw-mod"> 6926 <h3 class="panel__header dw-mod u-margin-bottom u-ta-center">@Translate("Shopping cart")</h3> 6927 <div class="panel__content-body panel__content-body--cart dw-mod"> 6928 <div class="js-handlebars-root u-flex grid--direction-column u-full-height dw-mod" id="miniCartContent" data-template="MiniCartContent" data-json-feed="/Default.aspx?ID=@miniCartFeedPageId&feedType=MiniCart" data-init-onload="false"></div> 6929 </div> 6930 </div> 6931 </div> 6932 </div> 6933 } 6934 6935 @helper RenderMiniCartModalLayout() 6936 { 6937 int miniCartFeedPageId = GetPageIdByNavigationTag("MiniCartFeed"); 6938 string cartPageLink = "/Default.aspx?ID=" + GetPageIdByNavigationTag("CartPage"); 6939 6940 <div class="mini-cart grid__cell dw-mod"> 6941 <input type="checkbox" id="miniCartTrigger" class="modal-trigger" autocomplete="off" /> 6942 <div class="modal-container dw-mod js-mini-cart" id="miniCart" data-cart-id="@miniCartFeedPageId" data-show-type="block" data-cart-page-link="@cartPageLink"> 6943 <label for="miniCartTrigger" class="modal-overlay"></label> 6944 <div class="modal modal--md modal--top-right dw-mod"> 6945 <div class="modal__body u-flex grid--direction-column dw-mod"> 6946 <h3 class="dw-mod u-ta-center">@Translate("Shopping cart")</h3> 6947 <div class="js-handlebars-root u-flex grid--direction-column dw-mod" id="miniCartContent" data-template="MiniCartContent" data-json-feed="/Default.aspx?ID=@miniCartFeedPageId&feedType=MiniCart" data-init-onload="false"></div> 6948 </div> 6949 <label class="modal__close-btn modal__close-btn--clean dw-mod" for="miniCartTrigger" title="@Translate("Close modal")"></label> 6950 </div> 6951 </div> 6952 </div> 6953 } 6954 6955 6956 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 6957 6958 @using System 6959 @using System.Web 6960 @using Dynamicweb.Rapido.Blocks.Extensibility 6961 @using Dynamicweb.Rapido.Blocks 6962 6963 @{ 6964 bool showOrderDraftLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("ShowOrderDraftIcon"); 6965 6966 Block masterDesktopActionsMenuOrderDraft = new Block 6967 { 6968 Id = "MasterDesktopActionsMenuOrderDraft", 6969 SortId = 40, 6970 Template = RenderOrderDraft() 6971 }; 6972 6973 if (showOrderDraftLink && Model.CurrentUser.ID > 0) 6974 { 6975 BlocksPage.GetBlockPage("Master").Add("MasterDesktopActionsMenu", masterDesktopActionsMenuOrderDraft); 6976 } 6977 } 6978 6979 @helper RenderOrderDraft() 6980 { 6981 int OrderDraftPageId = GetPageIdByNavigationTag("OrderDraft"); 6982 string OrderDraftPageLink = "/Default.aspx?ID=" + OrderDraftPageId; 6983 string draftIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("DraftIcon") != null ? Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("DraftIcon").SelectedValue : "fa fa-clipboard"; 6984 6985 6986 string topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 6987 string liClasses = topLayout != "normal" ? "menu__item--top-level u-hidden-xxs" : "menu--clean"; 6988 string menuLinkClass = topLayout != "normal" && topLayout != "splitted-center" ? "menu__link menu__link--icon" : "header-menu__link header-menu__link--icon"; 6989 6990 <li class="menu__item menu__item--horizontal @liClasses menu__item--icon dw-mod"> 6991 <a href="@OrderDraftPageLink" class="@menuLinkClass dw-mod" title="@Translate("My order drafts")"> 6992 <span class="u-inline u-position-relative"> 6993 <i class="@draftIcon fa-1_5x"></i> 6994 </span> 6995 </a> 6996 </li> 6997 } 6998 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 6999 7000 @using System 7001 @using System.Web 7002 @using Dynamicweb.Rapido.Blocks.Extensibility 7003 @using Dynamicweb.Rapido.Blocks 7004 7005 @{ 7006 bool showDownloadCartLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("ShowDownloadCart"); 7007 7008 Block masterDesktopActionsMenuDownloadCart = new Block 7009 { 7010 Id = "MasterDesktopActionsMenuDownloadCart", 7011 SortId = 50, 7012 Template = RenderDownloadCart() 7013 }; 7014 7015 if (showDownloadCartLink && Model.CurrentUser.ID > 0) 7016 { 7017 BlocksPage.GetBlockPage("Master").Add("MasterDesktopActionsMenu", masterDesktopActionsMenuDownloadCart); 7018 } 7019 } 7020 7021 @helper RenderDownloadCart() 7022 { 7023 int downloadCartPageId = GetPageIdByNavigationTag("DownloadCart"); 7024 string downloadCartPageLink = "/Default.aspx?ID=" + downloadCartPageId; 7025 7026 string topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 7027 string liClasses = topLayout != "normal" ? "menu__item--top-level u-hidden-xxs" : "menu--clean"; 7028 string menuLinkClass = topLayout != "normal" && topLayout != "splitted-center" ? "menu__link menu__link--icon" : "header-menu__link header-menu__link--icon"; 7029 string counterPosition = Model.Area.Item.GetItem("Ecommerce").GetItem("MiniCart").GetList("CounterPosition") != null ? Model.Area.Item.GetItem("Ecommerce").GetItem("MiniCart").GetList("CounterPosition").SelectedValue : "right"; 7030 7031 <li class="menu__item menu__item--horizontal @liClasses menu__item--icon dw-mod"> 7032 <a href="@downloadCartPageLink" class="@menuLinkClass dw-mod" title="@Translate("Download cart")"> 7033 <span class="u-inline u-position-relative"> 7034 <i class="fas fa-cart-arrow-down fa-1_5x"></i> 7035 <span class="mini-cart__counter u-hidden @(counterPosition == "right" ? "mini-cart__counter--inline" : "") dw-mod js-download-cart-counter"></span> 7036 </span> 7037 </a> 7038 </li> 7039 } 7040 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 7041 @using System 7042 @using System.Web 7043 @using Dynamicweb.Rapido.Blocks.Extensibility 7044 @using Dynamicweb.Rapido.Blocks 7045 @using Dynamicweb.Frontend 7046 7047 @functions { 7048 public class SearchConfiguration 7049 { 7050 public string searchFeedId { get; set; } 7051 public string searchSecondFeedId { get; set; } 7052 public int groupsFeedId { get; set; } 7053 public string resultPageLink { get; set; } 7054 public string searchPlaceholder { get; set; } 7055 public string searchType { get; set; } 7056 public string searchTemplate { get; set; } 7057 public string searchContentTemplate { get; set; } 7058 public string searchValue { get; set; } 7059 public bool showGroups { get; set; } 7060 7061 public SearchConfiguration() 7062 { 7063 searchFeedId = ""; 7064 searchSecondFeedId = ""; 7065 searchType = "product-search"; 7066 searchContentTemplate = ""; 7067 showGroups = true; 7068 } 7069 } 7070 7071 public class SommifyConfiguration 7072 { 7073 public ItemViewModel sommifySettings { get; set; } 7074 public bool sommifyIsActive { get; set; } = false; 7075 public bool sommifyIsActivated { get; set; } 7076 public string sommifyApi { get; set; } 7077 public string sommifyIcon { get; set; } 7078 public string sommifyStyling { get; set; } 7079 } 7080 7081 public string searchType() 7082 { 7083 return !string.IsNullOrEmpty(Model.Area.Item.GetItem("Layout").GetRawValueString("TopSearch")) ? Model.Area.Item.GetItem("Layout").GetRawValueString("TopSearch") : "productSearch"; 7084 } 7085 7086 public bool isProductSearchWithFilters() 7087 { 7088 return searchType() == "productSearchWithFilters"; 7089 } 7090 7091 public SommifyConfiguration GetSommifySettings() 7092 { 7093 SommifyConfiguration sommifyConfiguration = null; 7094 ItemViewModel sommifySettings = PageView.Current().AreaSettings.GetItem("Custom").GetItem("SommifySettings"); 7095 if (sommifySettings != null) 7096 { 7097 sommifyConfiguration = new SommifyConfiguration(); 7098 sommifyConfiguration.sommifySettings = sommifySettings; 7099 sommifyConfiguration.sommifyIsActivated = sommifySettings.GetBoolean("ActivateSommify"); 7100 sommifyConfiguration.sommifyApi = sommifySettings.GetRawValueString("SommifyApiKey"); 7101 sommifyConfiguration.sommifyIsActive = sommifyConfiguration.sommifyIsActivated && !string.IsNullOrEmpty(sommifyConfiguration.sommifyApi); 7102 7103 if (sommifyConfiguration.sommifyIsActive) 7104 { 7105 sommifyConfiguration.sommifyIcon = sommifySettings.GetRawValueString("SommifyIcon"); 7106 string sommifyBackgroundColor = sommifySettings.GetRawValueString("SommifyBackgroundColor"); 7107 sommifyConfiguration.sommifyStyling = !string.IsNullOrEmpty(sommifyBackgroundColor) ? "background-color: " + sommifyBackgroundColor + ";" : ""; 7108 } 7109 } 7110 7111 return sommifyConfiguration; 7112 } 7113 } 7114 @{ 7115 Block masterSearchBar = new Block 7116 { 7117 Id = "MasterSearchBar", 7118 SortId = 40, 7119 Template = RenderSearch("bar"), 7120 Design = new Design 7121 { 7122 Size = "auto", 7123 HidePadding = true, 7124 RenderType = RenderType.Column 7125 } 7126 }; 7127 7128 Block masterSearchAction = new Block 7129 { 7130 Id = "MasterDesktopActionsMenuSearch", 7131 SortId = 10, 7132 Template = RenderSearch() 7133 }; 7134 7135 BlocksPage.GetBlockPage("Master").Add("MasterHeader", masterSearchBar); 7136 BlocksPage.GetBlockPage("Master").Add("MasterDesktopActionsMenu", masterSearchAction); 7137 } 7138 7139 @helper RenderSearch(string type = "mini-search") 7140 { 7141 if (Model.ID != GetPageIdByNavigationTag("CartPage") && Model.ID != GetPageIdByNavigationTag("CheckoutPage")) 7142 { 7143 string productsSearchId = Converter.ToString(GetPageIdByNavigationTag("ProductSearchFeed")); 7144 int productsPageId = GetPageIdByNavigationTag("ProductsPage"); 7145 string contentSearchPageLink = GetPageIdByNavigationTag("ContentSearchResults") + "&Areaid=" + Model.Area.ID; 7146 7147 SearchConfiguration searchConfiguration = null; 7148 switch (searchType()) 7149 { 7150 case "contentSearch": 7151 searchConfiguration = new SearchConfiguration() 7152 { 7153 searchFeedId = GetPageIdByNavigationTag("ContentSearchFeed") + "&Areaid=" + Model.Area.ID + "&pagesOnly=true", 7154 resultPageLink = contentSearchPageLink, 7155 searchPlaceholder = Translate("Search page"), 7156 groupsFeedId = 0, 7157 searchType = "content-search", 7158 searchTemplate = "SearchPagesTemplate", 7159 showGroups = false 7160 }; 7161 break; 7162 case "productSearchWithFilters": 7163 searchConfiguration = new SearchConfiguration() 7164 { 7165 resultPageLink = Converter.ToString(productsPageId), 7166 searchFeedId = productsSearchId + "&feed=true", 7167 groupsFeedId = GetPageIdByNavigationTag("ProductGroupsFeed"), 7168 searchPlaceholder = Translate("Search products"), 7169 searchTemplate = "SearchResultsTypeAheadWithFilters", 7170 searchType = "product-search", 7171 showGroups = Model.Area.Item.GetItem("Layout").GetBoolean("ShowGroupsSelector") 7172 }; 7173 break; 7174 case "combinedSearch": 7175 searchConfiguration = new SearchConfiguration() 7176 { 7177 searchFeedId = productsSearchId + "&feed=true", 7178 searchSecondFeedId = GetPageIdByNavigationTag("ContentSearchFeed") + "&Areaid=" + Model.Area.ID + "&pagesOnly=true", 7179 resultPageLink = Converter.ToString(productsPageId), 7180 searchPlaceholder = Translate("Search products or pages"), 7181 groupsFeedId = GetPageIdByNavigationTag("ProductGroupsFeed"), 7182 searchType = "combined-search", 7183 searchTemplate = "SearchProductsTemplateWrap", 7184 searchContentTemplate = "SearchPagesTemplateWrap", 7185 showGroups = Model.Area.Item.GetItem("Layout").GetBoolean("ShowGroupsSelector") 7186 }; 7187 break; 7188 default: //productSearch 7189 searchConfiguration = new SearchConfiguration() 7190 { 7191 resultPageLink = Converter.ToString(productsPageId), 7192 searchFeedId = productsSearchId + "&feed=true", 7193 groupsFeedId = GetPageIdByNavigationTag("ProductGroupsFeed"), 7194 searchPlaceholder = Translate("Search products"), 7195 searchTemplate = "SearchResultsTypeAhead", 7196 searchType = "product-search", 7197 showGroups = Model.Area.Item.GetItem("Layout").GetBoolean("ShowGroupsSelector") 7198 }; 7199 break; 7200 } 7201 searchConfiguration.searchValue = HttpContext.Current.Request.QueryString.Get("Search") ?? ""; 7202 7203 if (type == "mini-search") 7204 { 7205 @RenderMiniSearch(searchConfiguration) 7206 } 7207 else 7208 { 7209 @RenderSearchBar(searchConfiguration) 7210 @RenderSearchModal(searchConfiguration) 7211 } 7212 } 7213 } 7214 7215 @helper RenderSearchModal(SearchConfiguration options) 7216 { 7217 bool isFavoritesPage = GetPageIdByNavigationTag("FavoriteProductsPage") > 0 ? PageView.Current().ID == GetPageIdByNavigationTag("FavoriteProductsPage") : false; 7218 SommifyConfiguration sommifyConfiguration = GetSommifySettings(); 7219 bool userIsImpersonating = Smartpage.PhilipsonWine.Ecommerce.Helpers.Helper.AllowsPartialPurchase(); 7220 7221 <input type="checkbox" id="SearchModalTrigger" class="modal-trigger @(isFavoritesPage ? "js-search-modal-trigger-input" : "") @(isProductSearchWithFilters() ? "search-modal-with-filters-trigger-input js-search-modal-with-filters-trigger-input" : "")"> 7222 <div class="modal-container @(isProductSearchWithFilters() ? "full-screen-search-modal-container js-full-screen-search-modal-container" : "")"> 7223 <label for="SearchModalTrigger" id="SearchModalOverlay" class="@(!isProductSearchWithFilters() ? "modal-overlay" : "")"></label> 7224 <div class="search-modal modal modal--xl modal-height--auto @(isProductSearchWithFilters() ? "search-modal-products-with-filters" : "js-search-modal")" id="SearchModal"> 7225 <div class="modal__body js-typeahead" 7226 data-search-feed-id="@options.searchFeedId" 7227 data-search-second-feed-id="@options.searchSecondFeedId" 7228 data-result-page-id="@options.resultPageLink" 7229 data-groups-page-id="@options.groupsFeedId" 7230 data-search-type="@options.searchType"> 7231 <div class="grid top-section"> 7232 <div class="contact-info grid__col-3 u-padding-left-none"> 7233 <div class="icon"> 7234 <img src="~/Files/Images/SvgIcons/phone.svg" alt="Alternate Text" /> 7235 </div> 7236 <div class="info"> 7237 <div class="info__header"> 7238 @Translate("Smartpage:Search.Modal.Questions", "Spørgsmål?") 7239 </div> 7240 <div class="info__phone"> 7241 @Translate("Smartpage:Search.Modal.PhoneInfo", "Ring tlf: +45 70 22 68 88") 7242 </div> 7243 </div> 7244 </div> 7245 <div class="typeahead u-color-inherit dw-mod custom__header__searchbar @(isProductSearchWithFilters() && !userIsImpersonating ? "js-custom-header-modal-searchbar" : "")" id="ProductSearchBar"> 7246 @if (options.showGroups) 7247 { 7248 <button type="button" class="btn btn--condensed u-color-light-gray--bg typeahead-group-btn dw-mod js-typeahead-groups-btn" data-group-id="all">@Translate("All")</button> 7249 <ul class="dropdown dropdown--absolute-position u-min-w220px js-handlebars-root js-typeahead-groups-content dw-mod" id="ProductSearchBarGroupsContent" data-template="SearchGroupsTemplate" data-json-feed="/Default.aspx?ID=@options.groupsFeedId&feedType=productGroups" data-init-onload="false" data-preloader="minimal"></ul> 7250 } 7251 <div class="typeahead-search-field"> 7252 <form action="@SearchEngineFriendlyURLs.GetFriendlyUrl(GetPageIdByNavigationTag("ProductsPage"))" id="SearchSubmitForm"> 7253 <input id="TypeaheadSearchField" type="text" class="u-no-margin u-full-width u-full-height js-typeahead-search-field js-ignore-click-outside search-input" placeholder="@HttpUtility.HtmlAttributeEncode(options.searchPlaceholder)" value="@HttpUtility.HtmlAttributeEncode(options.searchValue)" name="Search"> 7254 </form> 7255 </div> 7256 <button type="button" class="btn btn--condensed btn--primary u-no-margin dw-mod js-typeahead-enter-btn search-bar-icon" title="@HttpUtility.HtmlAttributeEncode(Translate("Search"))" style="@(sommifyConfiguration != null && sommifyConfiguration.sommifyIsActive ? "border-radius: 0px;" : "")"> 7257 @{ 7258 var customIcon = PageView.Current().AreaSettings.GetItem("Layout").GetFile("CustomSearchIcon"); 7259 if (customIcon != null) 7260 { 7261 <img src="@customIcon.Path" /> 7262 } 7263 else 7264 { 7265 <i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SearchIcon").SelectedValue"></i> 7266 } 7267 } 7268 7269 </button> 7270 7271 @if (sommifyConfiguration != null && sommifyConfiguration.sommifyIsActive) 7272 { 7273 @RenderSommifyOnSearchBar(sommifyConfiguration) 7274 } 7275 </div> 7276 <div class="u-flex u-flex--row modal-close-wrapper"> 7277 <span class="info-text__close-button">@Translate("Smartpage:Search.Modal.Close", "Luk vindue")</span><label class="modal__close-btn @(isProductSearchWithFilters() ? "js-search-modal-close-btn" : "")" for="SearchModalTrigger"></label> 7278 </div> 7279 </div> 7280 <div class="grid"> 7281 @RenderSearchContent(options.searchTemplate) 7282 </div> 7283 </div> 7284 </div> 7285 </div> 7286 } 7287 7288 @helper RenderSearchContent(string template) 7289 { 7290 <div class="js-typeahead-search-content grid u-flex--row typeahead-search-content" id="ProductSearchBarContent" data-template="@template" data-init-onload="false" data-pre-render-template="ProductSearchPreRenderContainer"></div> 7291 } 7292 7293 @helper RenderSearchBar(SearchConfiguration options) 7294 { 7295 bool isFavoritesPage = GetPageIdByNavigationTag("FavoriteProductsPage") > 0 ? PageView.Current().ID == GetPageIdByNavigationTag("FavoriteProductsPage") : false; 7296 7297 if (isFavoritesPage) 7298 { 7299 <div class="favorites-page-confirm-search-overlay js-favorites-page-confirm-search-overlay"></div> 7300 <div class="favorites-page-confirm-search js-favorites-page-confirm-search"> 7301 <div class="favorites-page-confirm-search-body"> 7302 <div class="confirm-search-header">@Translate("Smartpage:Search.Modal.FavoritesSearchPrompt", "Ønsker du at søge efter varer i din favoritliste?")</div> 7303 <div class="confirm-search-buttons-container"> 7304 <div class="btn btn--secondary dw-mod js-favorites-search-decline">@Translate("Smartpage:Search.Modal.FavoritesSearchPrompt.DeclineButton", "Nej, søg på alle produkter")</div> 7305 <div class="btn btn--primary dw-mod js-favorites-search-accept">@Translate("Smartpage:Search.Modal.FavoritesSearchPrompt.AcceptButton", "Ja, søg i favoritlisten")</div> 7306 </div> 7307 </div> 7308 </div> 7309 } 7310 7311 string searchModalTriggerClasses = ""; 7312 searchModalTriggerClasses += "js-search-modal-trigger-focus-onclick"; 7313 7314 if (isProductSearchWithFilters()) 7315 { 7316 searchModalTriggerClasses += " js-search-modal-with-filters-trigger"; 7317 } 7318 7319 SommifyConfiguration sommifyConfiguration = GetSommifySettings(); 7320 7321 <div class="typeahead typeahead--centered u-color-inherit custom__header__searchbar @(isProductSearchWithFilters() ? "js-custom-header-searchbar" : "")" id="ProductSearchBar"> 7322 <div class="typeahead-search-field"> 7323 <label for="SearchModalTrigger" class="search-modal-trigger js-search-modal-trigger @searchModalTriggerClasses"></label> 7324 <input type="text" class="u-no-margin u-full-width u-full-height" placeholder="@HttpUtility.HtmlAttributeEncode(options.searchPlaceholder)" value="@HttpUtility.HtmlAttributeEncode(options.searchValue)" name="Search"> 7325 </div> 7326 <button type="button" class="btn btn--condensed btn--primary u-no-margin dw-mod search-bar-icon" title="@HttpUtility.HtmlAttributeEncode(Translate("Search"))" style="@(sommifyConfiguration != null && sommifyConfiguration.sommifyIsActive ? "border-radius: 0px;" : "")"> 7327 @{ 7328 var customIcon = PageView.Current().AreaSettings.GetItem("Layout").GetFile("CustomSearchIcon"); 7329 if (customIcon != null) 7330 { 7331 <img src="@customIcon.Path" /> 7332 } 7333 else 7334 { 7335 <i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SearchIcon").SelectedValue"></i> 7336 } 7337 } 7338 7339 </button> 7340 7341 @if (sommifyConfiguration != null && sommifyConfiguration.sommifyIsActive) 7342 { 7343 @RenderSommifyOnSearchBar(sommifyConfiguration) 7344 } 7345 </div> 7346 } 7347 7348 @helper RenderSommifyOnSearchBar(SommifyConfiguration sommifyConfiguration) 7349 { 7350 <div class="header-menu__link header-menu__link--icon sommify-header-container js-sommify-widget-activator dw-mod" style="@sommifyConfiguration.sommifyStyling"> 7351 <div class="custom__header__icon__icon"> 7352 @if (!string.IsNullOrEmpty(sommifyConfiguration.sommifyIcon)) 7353 { 7354 <img class="sommify-header-icon" src="@sommifyConfiguration.sommifyIcon" /> 7355 } 7356 </div> 7357 <div class="custom__header__icon__text sommify-header-text"> 7358 @Translate("Smartpage:Header.Sommify.Text", "Wine AI") 7359 </div> 7360 </div> 7361 } 7362 7363 @helper RenderMiniSearch(SearchConfiguration options) 7364 { 7365 string topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 7366 string menuLinkClass = topLayout != "normal" && topLayout != "splitted-center" ? "menu__link menu__link--icon" : "header-menu__link header-menu__link--icon"; 7367 7368 <li class="menu__item menu__item--horizontal menu__item--top-level menu__item--icon u-hidden-xxs is-dropdown is-dropdown--no-icon dw-mod" id="miniSearchIcon"> 7369 <div class="@menuLinkClass dw-mod" title="@Translate("Search")"> 7370 <i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SearchIcon").SelectedValue fa-1_5x"></i> 7371 </div> 7372 <div class="menu menu--dropdown menu--dropdown-right u-no-padding u-w380px grid__cell dw-mod"> 7373 <div class="typeahead js-typeahead" id="ProductSearchBar" 7374 data-page-size="7" 7375 data-search-feed-id="@options.searchFeedId" 7376 data-search-second-feed-id="@options.searchSecondFeedId" 7377 data-result-page-id="@options.resultPageLink" 7378 data-search-type="@options.searchType"> 7379 <div class="typeahead-search-field"> 7380 <input type="text" class="u-no-margin u-full-width js-typeahead-search-field" id="headerSearch" data-shop-id="@Pageview.Area.EcomShopId" data-area-id="@Dynamicweb.Core.Converter.ToString(Pageview.AreaID)" placeholder="@options.searchPlaceholder" value="@options.searchValue"> 7381 @if (string.IsNullOrEmpty(options.searchSecondFeedId)) 7382 { 7383 <ul class="dropdown dropdown--absolute-position u-min-w220px u-full-width js-handlebars-root js-typeahead-search-content dw-mod" id="ProductSearchBarContent" data-template="@options.searchTemplate" data-json-feed="/Default.aspx?ID=@options.searchFeedId&feedType=productsOnly" data-init-onload="false"></ul> 7384 } 7385 else 7386 { 7387 <div class="dropdown dropdown--absolute-position dropdown--combined grid dropdown--right-aligned"> 7388 <div class="js-handlebars-root js-typeahead-search-content grid__col-sm-7 grid__col--bleed-y" id="ProductSearchBarContent" data-template="@options.searchTemplate" data-json-feed="/Default.aspx?ID=@options.searchFeedId&feedType=productsOnly" data-init-onload="false"></div> 7389 <div class="js-handlebars-root js-typeahead-additional-search-content grid__col-sm-5 grid__col--bleed-y" id="ContentSearchBarContent" data-template="@options.searchContentTemplate" data-json-feed="/Default.aspx?ID=@options.searchSecondFeedId" data-init-onload="false"></div> 7390 </div> 7391 } 7392 </div> 7393 </div> 7394 </div> 7395 </li> 7396 } 7397 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 7398 7399 @using System 7400 @using System.Web 7401 @using Dynamicweb.Rapido.Blocks.Extensibility 7402 @using Dynamicweb.Rapido.Blocks 7403 7404 @{ 7405 string headerConfigurationTopLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 7406 bool headerConfigurationHideSearch = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("HideSearch"); 7407 7408 BlocksPage headerConfigurationPage = BlocksPage.GetBlockPage("Master"); 7409 7410 Block configDesktopLogo = headerConfigurationPage.GetBlockById("MasterDesktopLogo"); 7411 headerConfigurationPage.RemoveBlock(configDesktopLogo); 7412 7413 Block configDesktopMenu = headerConfigurationPage.GetBlockById("MasterDesktopMenu"); 7414 headerConfigurationPage.RemoveBlock(configDesktopMenu); 7415 7416 Block configSearchBar = headerConfigurationPage.GetBlockById("MasterSearchBar"); 7417 headerConfigurationPage.RemoveBlock(configSearchBar); 7418 7419 Block configSearchAction = headerConfigurationPage.GetBlockById("MasterDesktopActionsMenuSearch"); 7420 headerConfigurationPage.RemoveBlock(configSearchAction); 7421 7422 Block configDesktopActionsMenu = headerConfigurationPage.GetBlockById("MasterDesktopActionsMenu"); 7423 headerConfigurationPage.RemoveBlock(configDesktopActionsMenu); 7424 7425 Block configDesktopExtra = headerConfigurationPage.GetBlockById("MasterDesktopExtra"); 7426 7427 switch (headerConfigurationTopLayout) 7428 { 7429 case "condensed": //2 7430 configDesktopLogo.Design.Size = "auto-width"; 7431 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopLogo); 7432 7433 configDesktopMenu.SortId = 20; 7434 configDesktopMenu.Design.Size = "auto"; 7435 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopMenu); 7436 7437 configDesktopActionsMenu.SortId = 30; 7438 configDesktopActionsMenu.Design.Size = "auto-width"; 7439 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopActionsMenu); 7440 7441 if (!headerConfigurationHideSearch) 7442 { 7443 configSearchBar.SortId = 40; 7444 configSearchBar.Design.Size = "12"; 7445 configDesktopExtra.SortId = 50; 7446 headerConfigurationPage.Add("MasterDesktopExtra", configSearchBar); 7447 } 7448 break; 7449 case "splitted": //3 7450 configDesktopLogo.Design.Size = "auto"; 7451 headerConfigurationPage.Add("MasterDesktopExtra", configDesktopLogo); 7452 7453 if (!headerConfigurationHideSearch) 7454 { 7455 configSearchBar.SortId = 20; 7456 configSearchBar.Design.Size = "auto"; 7457 headerConfigurationPage.Add("MasterDesktopExtra", configSearchBar); 7458 } 7459 7460 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopMenu); 7461 7462 configDesktopActionsMenu.SortId = 20; 7463 configDesktopActionsMenu.Design.Size = "auto-width"; 7464 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopActionsMenu); 7465 break; 7466 case "splitted-center": //4 7467 configDesktopLogo.Design.Size = "auto"; 7468 headerConfigurationPage.Add("MasterDesktopExtra", configDesktopLogo); 7469 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopMenu); 7470 7471 configDesktopActionsMenu.SortId = 30; 7472 configDesktopActionsMenu.Design.Size = "auto-width"; 7473 headerConfigurationPage.Add("MasterDesktopExtra", configDesktopActionsMenu); 7474 7475 if (!headerConfigurationHideSearch) 7476 { 7477 headerConfigurationPage.Add("MasterDesktopActionsMenu", configSearchAction); 7478 } 7479 break; 7480 case "minimal": //5 7481 configDesktopLogo.Design.Size = "auto-width"; 7482 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopLogo); 7483 7484 configDesktopMenu.Design.Size = "auto"; 7485 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopMenu); 7486 7487 configDesktopActionsMenu.SortId = 20; 7488 configDesktopActionsMenu.Design.Size = "auto-width"; 7489 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopActionsMenu); 7490 7491 if (!headerConfigurationHideSearch) 7492 { 7493 headerConfigurationPage.Add("MasterDesktopActionsMenu", configSearchAction); 7494 } 7495 break; 7496 case "minimal-center": //6 7497 configDesktopLogo.Design.Size = "auto-width"; 7498 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopLogo); 7499 7500 configDesktopMenu.Design.Size = "auto"; 7501 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopMenu); 7502 7503 configDesktopActionsMenu.SortId = 20; 7504 configDesktopActionsMenu.Design.Size = "auto-width"; 7505 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopActionsMenu); 7506 7507 if (!headerConfigurationHideSearch) 7508 { 7509 headerConfigurationPage.Add("MasterDesktopActionsMenu", configSearchAction); 7510 } 7511 break; 7512 case "minimal-right": //7 7513 configDesktopLogo.Design.Size = "auto-width"; 7514 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopLogo); 7515 7516 configDesktopMenu.Design.Size = "auto"; 7517 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopMenu); 7518 7519 configDesktopActionsMenu.SortId = 20; 7520 configDesktopActionsMenu.Design.Size = "auto-width"; 7521 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopActionsMenu); 7522 7523 if (!headerConfigurationHideSearch) 7524 { 7525 headerConfigurationPage.Add("MasterDesktopActionsMenu", configSearchAction); 7526 } 7527 break; 7528 case "two-lines": //8 7529 configDesktopLogo.Design.Size = "auto"; 7530 headerConfigurationPage.Add("MasterDesktopExtra", configDesktopLogo); 7531 7532 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopMenu); 7533 7534 configDesktopActionsMenu.SortId = 20; 7535 configDesktopActionsMenu.Design.Size = "auto-width"; 7536 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopActionsMenu); 7537 7538 if (!headerConfigurationHideSearch) 7539 { 7540 headerConfigurationPage.Add("MasterDesktopActionsMenu", configSearchAction); 7541 } 7542 break; 7543 case "two-lines-centered": //9 7544 configDesktopLogo.Design.Size = "auto"; 7545 headerConfigurationPage.Add("MasterDesktopExtra", configDesktopLogo); 7546 7547 configDesktopMenu.Design.Size = "auto-width"; 7548 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopMenu); 7549 7550 configDesktopActionsMenu.SortId = 20; 7551 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopActionsMenu); 7552 7553 if (!headerConfigurationHideSearch) 7554 { 7555 headerConfigurationPage.Add("MasterDesktopActionsMenu", configSearchAction); 7556 } 7557 break; 7558 case "normal": //1 7559 default: 7560 headerConfigurationPage.Add("MasterDesktopExtra", configDesktopLogo); 7561 7562 if (!headerConfigurationHideSearch) 7563 { 7564 configSearchBar.SortId = 20; 7565 headerConfigurationPage.Add("MasterDesktopExtra", configSearchBar); 7566 } 7567 7568 configDesktopActionsMenu.SortId = 30; 7569 headerConfigurationPage.Add("MasterDesktopExtra", configDesktopActionsMenu); 7570 7571 configDesktopActionsMenu.Design.Size = "auto-width"; 7572 headerConfigurationPage.Add("MasterDesktopNavigation", configDesktopMenu); 7573 break; 7574 } 7575 } 7576 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 7577 @using Dynamicweb.Rapido.Blocks 7578 @using Dynamicweb.Core; 7579 7580 @{ 7581 var user = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser(); 7582 if (user != null && user.AllowBackend) 7583 { 7584 var editorsGroup = Pageview.AreaSettings.GetItem("Custom").GetRawValue("EditorsGroup"); 7585 if (user.GroupsIds.Contains(Converter.ToInt32(editorsGroup))) 7586 { 7587 Block ShowPageIdBlock = new Block 7588 { 7589 Id = "ShowPageId", 7590 SortId = -10, 7591 Template = RenderShowPageIdSection(), 7592 Design = new Design 7593 { 7594 Size = "auto-width", 7595 HidePadding = true, 7596 RenderType = RenderType.Column, 7597 CssClass = "grid--align-self-center" 7598 } 7599 }; 7600 7601 BlocksPage.GetBlockPage("Master").Add("MasterHeader", ShowPageIdBlock); 7602 } 7603 } 7604 7605 } 7606 7607 @helper RenderShowPageIdSection() 7608 { 7609 <div class="u-ta-center u-padding" style="background-color:#fecd00"> 7610 @Translate("Smartpage:Header.ClickToCopy", "Tryk på side id for at kopiere:") <span onclick="navigator.clipboard.writeText(event.innerText)" class="u-bold u-underline u-pointer">@Pageview.ID</span> 7611 </div> 7612 } 7613 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 7614 @using System.Web 7615 @using Dynamicweb.Rapido.Blocks 7616 @using Dynamicweb; 7617 @using Dynamicweb.Core; 7618 @using System.Text.RegularExpressions 7619 @using Dynamicweb.Ecommerce.International 7620 7621 @{ 7622 if (Model.ID != GetPageIdByNavigationTag("CartPage") && Model.ID != GetPageIdByNavigationTag("CheckoutPage")) 7623 { 7624 Block masterToolbar = new Block 7625 { 7626 Id = "MasterToolbar", 7627 SortId = 0, 7628 Template = RenderToolbar(), 7629 Design = new Design 7630 { 7631 Size = "auto-width", 7632 HidePadding = true, 7633 RenderType = RenderType.Column, 7634 CssClass = "grid--align-self-center custom__header__toolbar js-custom__header__toolbar" 7635 } 7636 }; 7637 7638 BlocksPage.GetBlockPage("Master").Add("MasterHeader", masterToolbar); 7639 } 7640 } 7641 7642 @helper RenderToolbar() 7643 { 7644 string trustpilotFreeWidget = Model.Area.Item.GetItem("Custom").GetRawValueString("HeaderTrustpilotWidget"); 7645 var headerUsp = Pageview.AreaSettings.GetItem("Custom").GetItem("CustomSettings").GetItems("HeaderUSP"); 7646 <div class="center-container grid top-container__center-container dw-mod"> 7647 <div class="grid grid--align-center custom__header__usp__container"> 7648 <div> 7649 <ul class="u-flex custom__header__usp"> 7650 @foreach (var usp in headerUsp) 7651 { 7652 var icon = usp.GetFile("Icon"); 7653 <li class="u-flex whitespace-nowrap"> 7654 @if (!string.IsNullOrWhiteSpace(usp.GetString("Link"))) 7655 { 7656 <a class="u-flex" href="@usp.GetString("Link")"> 7657 @{ 7658 if (icon != null) 7659 { 7660 <img class="u-margin-right" src="@icon.Path" alt="@HttpUtility.HtmlAttributeEncode(usp.GetString("Label"))" /> 7661 } 7662 else 7663 { 7664 <i class="fa fa-check u-margin-right u-flex u-flex--align-center"></i> 7665 } 7666 } 7667 @usp.GetString("Label") 7668 </a> 7669 } 7670 else 7671 { 7672 if (icon != null) 7673 { 7674 <img class="u-margin-right" src="@icon.Path" alt="@HttpUtility.HtmlAttributeEncode(usp.GetString("Label"))" /> 7675 } 7676 else 7677 { 7678 <i class="fa fa-check u-margin-right u-flex u-flex--align-center"></i> 7679 } @usp.GetString("Label") 7680 } 7681 </li> 7682 } 7683 </ul> 7684 </div> 7685 @if (!string.IsNullOrEmpty(trustpilotFreeWidget)) 7686 { 7687 <div> 7688 @trustpilotFreeWidget 7689 </div> 7690 } 7691 <div class="u-align-right custom__header__contacttext"> 7692 @Translate("Smartpage:Header.ContactText", "Har du brug for hjælp eller vejledning? +45 70226888") 7693 </div> 7694 <div class="u-align-right currency-selector"> 7695 @RenderCurrencySelectorSmall() 7696 </div> 7697 <div class="u-align-right language-selector"> 7698 @RenderLanguageSelectorSmall() 7699 </div> 7700 </div> 7701 </div> 7702 } 7703 7704 @helper RenderCurrencySelectorSmall() 7705 { 7706 List<Currency> currencies = Dynamicweb.Ecommerce.Services.Currencies.GetCurrenciesForLanguage(Dynamicweb.Ecommerce.Common.Context.LanguageID).ToList(); 7707 7708 if (currencies.Count > 1) 7709 { 7710 bool languageSelectionFromCookie = Dynamicweb.Environment.CookieManager.GetCookie("ActiveLanguageSelection") != null && Converter.ToBoolean(Dynamicweb.Environment.CookieManager.GetCookie("ActiveLanguageSelection").Value); 7711 var topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout")?.SelectedValue ?? "normal"; 7712 var liClasses = topLayout != "normal" ? "menu__item--top-level u-hidden-xxs" : "menu--clean"; 7713 7714 <li class="menu__item menu__item--horizontal @liClasses menu__item--icon is-dropdown is-dropdown--no-icon dw-mod"> 7715 <div class="current-currency u-flex u-flex--row"> 7716 @Dynamicweb.Ecommerce.Common.Context.Currency.Code 7717 </div> 7718 <div class="menu menu--dropdown menu--dropdown-right currencies-dropdown grid__cell dw-mod"> 7719 @foreach (Currency currency in currencies) 7720 { 7721 var pageId = Pageview.Page.ID; 7722 7723 if (!languageSelectionFromCookie) 7724 { 7725 var currencyLanguageMapping = Pageview.AreaSettings.GetItem("Custom").GetItems("CurrencyLanguageMapping")?.FirstOrDefault(m => m.GetRawValueString("Currency") == currency.Code); 7726 if (currencyLanguageMapping != null) 7727 { 7728 var language = Model.Languages.FirstOrDefault(l => l.ID == Converter.ToInt32(currencyLanguageMapping.GetRawValueString("Language"))); 7729 7730 if (language != null) 7731 { 7732 pageId = language.Page.ID; 7733 } 7734 } 7735 } 7736 7737 var qs = HttpUtility.ParseQueryString(Dynamicweb.Context.Current.Request.QueryString.ToString()); 7738 qs.Set("ID", Converter.ToString(pageId)); 7739 qs.Set("CurrencyCode", currency.Code); 7740 string url = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?" + qs); 7741 7742 var activeClass = currency.Code == Dynamicweb.Ecommerce.Common.Context.Currency.Code ? "u-bold" : string.Empty; 7743 7744 <div class="menu__item dw-mod"> 7745 <a href="@url" class="menu-dropdown__link dw-mod u-flex @(activeClass)">@currency.Code</a> 7746 </div> 7747 } 7748 </div> 7749 </li> 7750 } 7751 } 7752 7753 @helper RenderLanguageSelectorSmall() 7754 { 7755 string topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 7756 string liClasses = topLayout != "normal" ? "menu__item--top-level u-hidden-xxs" : "menu--clean"; 7757 string menuLinkClass = topLayout != "normal" && topLayout != "splitted-center" ? "menu__link menu__link--icon" : "header-menu__link header-menu__link--icon"; 7758 string languageViewType = !string.IsNullOrEmpty(Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("LanguageSelector").SelectedValue) ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("LanguageSelector").SelectedValue.ToLower() : ""; 7759 7760 var languages = Model.Languages.Where(l => Dynamicweb.Services.Areas.GetArea(l.ID).Published).ToList(); 7761 7762 if (languages.Count > 1) 7763 { 7764 <li class="menu__item menu__item--horizontal @liClasses menu__item--icon is-dropdown is-dropdown--no-icon dw-mod"> 7765 <div class="current-language u-flex u-flex--row"> 7766 @{ 7767 var currentLanguage = Model.Languages.First(l => l.IsCurrent); 7768 var currentArea = Dynamicweb.Services.Areas.GetArea(currentLanguage.ID); 7769 string currentCultureName = Regex.Replace(currentArea.CultureInfo.NativeName, @" ?\(.*?\)", string.Empty); 7770 currentCultureName = char.ToUpper(currentCultureName[0]) + currentCultureName.Substring(1); 7771 string currentLanguageInfo = "<span class=\"flag-icon flag-icon-" + currentArea.EcomCountryCode.ToLower() + " u-margin-right\"></span>" + currentCultureName; 7772 } 7773 @currentLanguageInfo 7774 </div> 7775 <div class="menu menu--dropdown menu--dropdown-right languages-dropdown dw-mod grid__cell"> 7776 @foreach (var lang in languages) 7777 { 7778 var area = Dynamicweb.Services.Areas.GetArea(lang.ID); 7779 var qs = HttpUtility.ParseQueryString(System.Web.HttpContext.Current.Request.QueryString.ToString()); 7780 qs.Set("ID", Converter.ToString(lang.Page.ID)); 7781 qs.Set("CurrencyCode", area.EcomCurrencyId); 7782 qs.Set("ActiveLanguageSelection", "True"); 7783 string url = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?" + qs); 7784 string primaryDomain = area.DomainLock; 7785 7786 if (!string.IsNullOrWhiteSpace(primaryDomain)) 7787 { 7788 url = HttpContext.Current.Request.Url.Scheme + "://" + primaryDomain + url; 7789 } 7790 else 7791 { 7792 url = HttpContext.Current.Request.Url.Scheme + "://" + area.Domain.Split(new string[] { Environment.NewLine }, StringSplitOptions.None).First() + url; 7793 } 7794 7795 7796 string widthClass = "menu__item--fixed-width"; 7797 string langInfo = "<span class=\"flag-icon flag-icon-" + area.EcomCountryCode.ToLower() + " u-margin-right\"></span>" + lang.Name; 7798 string cultureName = Regex.Replace(area.CultureInfo.NativeName, @" ?\(.*?\)", string.Empty); 7799 cultureName = char.ToUpper(cultureName[0]) + cultureName.Substring(1); 7800 string activeClass = Dynamicweb.Ecommerce.Common.Context.LanguageID == area.EcomLanguageId ? "u-bold" : string.Empty; 7801 7802 if (languageViewType == "flag-culture") 7803 { 7804 langInfo = "<span class=\" u-margin-right flag-icon flag-icon-" + area.EcomCountryCode.ToLower() + " \"></span> " + cultureName; 7805 } 7806 7807 if (languageViewType == "flag") 7808 { 7809 langInfo = "<span class=\" u-margin-right flag-icon flag-icon-" + area.EcomCountryCode.ToLower() + " \"></span>"; 7810 widthClass = ""; 7811 } 7812 7813 if (languageViewType == "name") 7814 { 7815 langInfo = lang.Name; 7816 } 7817 7818 if (languageViewType == "culture") 7819 { 7820 langInfo = cultureName; 7821 widthClass = ""; 7822 } 7823 7824 if (url.Contains("/forside")) 7825 { 7826 url = url.Replace("/forside", ""); 7827 } 7828 7829 <div class="menu__item dw-mod @widthClass"> 7830 <a href="@url" class="menu-dropdown__link dw-mod u-flex @activeClass">@langInfo</a> 7831 </div> 7832 } 7833 </div> 7834 </li> 7835 } 7836 } 7837 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 7838 7839 @using System 7840 @using System.Web 7841 @using Dynamicweb.Rapido.Blocks.Extensibility 7842 @using Dynamicweb.Rapido.Blocks 7843 7844 @{ 7845 Block masterDesktopActionsOffers = new Block 7846 { 7847 Id = "MasterDesktopActionsOffers", 7848 SortId = 10, 7849 Template = RenderOffers() 7850 }; 7851 7852 @*BlocksPage.GetBlockPage("Master").Add("MasterDesktopActionsMenu", masterDesktopActionsOffers);*@ 7853 } 7854 7855 @helper RenderOffers() 7856 { 7857 <li class="menu__item menu__item--horizontal menu__item menu__item--icon menu__item--clean is-dropdown is-dropdown--no-icon dw-mod"> 7858 <div class="header-menu__link header-menu__link--icon dw-mod"> 7859 <div class="custom__header__icon"> 7860 <a href="/Default.aspx?ID=@GetPageIdByNavigationTag("OffersPage")"> 7861 <div class="custom__header__icon__icon"> 7862 <svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 7863 <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 7864 <g id="Header" transform="translate(-1289.000000, -56.000000)" fill-rule="nonzero"> 7865 <g id="TILBUD"> 7866 <g transform="translate(1289.000000, 56.000000)"> 7867 <polygon id="Path" fill="#FFCB00" points="43.87725 23.9999062 47.9999063 17.569125 41.2140938 14.0612813 41.569125 6.4306875 33.9385313 6.785625 30.4306875 0 24 4.1225625 17.5692188 0 14.061375 6.78571875 6.430875 6.43078125 6.7858125 14.061375 0 17.569125 4.12265625 23.9999062 0 30.4306875 6.78571875 33.9385312 6.4306875 41.569125 14.0612813 41.2141875 17.569125 48 24 43.8771562 30.4307812 47.9997187 33.938625 41.2140938 41.5692188 41.5690313 41.2141875 33.9384375 48 30.4305937"></polygon> 7868 <path d="M15.68,27.072 C16.544,27.072 17.342,26.904 18.074,26.568 C18.806,26.232 19.442,25.74 19.982,25.092 C20.522,24.444 20.948,23.658 21.26,22.734 C21.572,21.81 21.728,20.76 21.728,19.584 C21.728,18.408 21.572,17.364 21.26,16.452 C20.948,15.54 20.522,14.766 19.982,14.13 C19.442,13.494 18.806,13.008 18.074,12.672 C17.342,12.336 16.544,12.168 15.68,12.168 C14.816,12.168 14.012,12.336 13.268,12.672 C12.524,13.008 11.882,13.494 11.342,14.13 C10.802,14.766 10.382,15.54 10.082,16.452 C9.782,17.364 9.632,18.408 9.632,19.584 C9.632,20.76 9.782,21.81 10.082,22.734 C10.382,23.658 10.802,24.444 11.342,25.092 C11.882,25.74 12.524,26.232 13.268,26.568 C14.012,26.904 14.816,27.072 15.68,27.072 Z M20,36.432 L32.528,12.168 L29.072,12.168 L16.544,36.432 L20,36.432 Z M15.68,23.688 C15.2,23.688 14.78,23.4 14.42,22.824 C14.06,22.248 13.88,21.168 13.88,19.584 C13.88,18.792 13.928,18.138 14.024,17.622 C14.12,17.106 14.252,16.692 14.42,16.38 C14.588,16.068 14.78,15.852 14.996,15.732 C15.212,15.612 15.44,15.552 15.68,15.552 C15.92,15.552 16.148,15.612 16.364,15.732 C16.58,15.852 16.772,16.068 16.94,16.38 C17.108,16.692 17.24,17.106 17.336,17.622 C17.432,18.138 17.48,18.792 17.48,19.584 C17.48,21.168 17.3,22.248 16.94,22.824 C16.58,23.4 16.16,23.688 15.68,23.688 Z M33.32,36.432 C34.184,36.432 34.982,36.264 35.714,35.928 C36.446,35.592 37.082,35.1 37.622,34.452 C38.162,33.804 38.588,33.018 38.9,32.094 C39.212,31.17 39.368,30.12 39.368,28.944 C39.368,27.768 39.212,26.724 38.9,25.812 C38.588,24.9 38.162,24.126 37.622,23.49 C37.082,22.854 36.446,22.368 35.714,22.032 C34.982,21.696 34.184,21.528 33.32,21.528 C32.456,21.528 31.652,21.696 30.908,22.032 C30.164,22.368 29.522,22.854 28.982,23.49 C28.442,24.126 28.022,24.9 27.722,25.812 C27.422,26.724 27.272,27.768 27.272,28.944 C27.272,30.12 27.422,31.17 27.722,32.094 C28.022,33.018 28.442,33.804 28.982,34.452 C29.522,35.1 30.164,35.592 30.908,35.928 C31.652,36.264 32.456,36.432 33.32,36.432 Z M33.32,33.048 C32.84,33.048 32.42,32.76 32.06,32.184 C31.7,31.608 31.52,30.528 31.52,28.944 C31.52,28.152 31.568,27.498 31.664,26.982 C31.76,26.466 31.892,26.052 32.06,25.74 C32.228,25.428 32.42,25.212 32.636,25.092 C32.852,24.972 33.08,24.912 33.32,24.912 C33.56,24.912 33.788,24.972 34.004,25.092 C34.22,25.212 34.412,25.428 34.58,25.74 C34.748,26.052 34.88,26.466 34.976,26.982 C35.072,27.498 35.12,28.152 35.12,28.944 C35.12,30.528 34.94,31.608 34.58,32.184 C34.22,32.76 33.8,33.048 33.32,33.048 Z" id="%" fill="#000000"></path> 7869 </g> 7870 </g> 7871 </g> 7872 </g> 7873 </svg> 7874 </div> 7875 <div class="custom__header__icon__text yellow"> 7876 @Translate("Smartpage:Header.IconsText.Tilbud!", "Tilbud!") 7877 </div> 7878 </a> 7879 </div> 7880 </div> 7881 </li> 7882 7883 } 7884 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 7885 @using Dynamicweb.Rapido.Blocks 7886 7887 @{ 7888 bool activateOfferNewspaper = Pageview.AreaSettings.GetItem("Custom").GetBoolean("ActivateOfferNewspaper"); 7889 bool activatePriceBook = Pageview.AreaSettings.GetItem("Custom").GetBoolean("ActivateHeaderPriceBook"); 7890 if (activateOfferNewspaper) 7891 { 7892 Block masterDesktopActionsOfferNewspaperBlock = new Block 7893 { 7894 Id = "MasterDesktopActionsOfferNewspaper", 7895 SortId = 10, 7896 Template = RenderOfferNewspaper() 7897 }; 7898 7899 BlocksPage.GetBlockPage("Master").Add("MasterDesktopActionsMenu", masterDesktopActionsOfferNewspaperBlock); 7900 } 7901 7902 if (activatePriceBook && Model.CurrentUser.ID > 0) 7903 { 7904 var priceBookList = Dynamicweb.Ecommerce.CustomerCenter.CustomerProductList.GetListByCustomerId(Converter.ToInt32(Model.CurrentUser.ID))?.FirstOrDefault(l => l.Type == "PriceBookList"); 7905 if (priceBookList != null) 7906 { 7907 string link = $"/Default.aspx?Id={GetPageIdByNavigationTag("FavoriteProductsPage")}&ListID={priceBookList.ID}&ListName={priceBookList.Name}"; 7908 Block masterDesktopActionsPriceBoookBlock = new Block 7909 { 7910 Id = "MasterDesktopActionsPriceBook", 7911 SortId = 10, 7912 Template = RenderPriceBook(link, Translate("Smartpage:Header.PriceBookText.PriceBook", "Din prisbog"), "fal fa-dollar-sign") 7913 }; 7914 7915 BlocksPage.GetBlockPage("Master").Add("MasterDesktopActionsMenu", masterDesktopActionsPriceBoookBlock); 7916 } 7917 } 7918 } 7919 7920 @helper RenderOfferNewspaper() 7921 { 7922 string newsPaperLink = Pageview.AreaSettings.GetItem("Custom").GetString("OfferNewspaperLink"); 7923 7924 <li class="menu__item menu__item--horizontal menu__item menu__item--icon menu__item--clean is-dropdown is-dropdown--no-icon dw-mod"> 7925 <div class="header-menu__link header-menu__link--icon dw-mod"> 7926 <div class="custom__header__icon"> 7927 <a href="@newsPaperLink"> 7928 <div class="custom__header__icon__icon newspaper-icon"> 7929 @RenderOfferNewspaperIcon() 7930 </div> 7931 <div class="custom__header__icon__text"> 7932 <div> 7933 <div class="custom__header__icon__text"> 7934 @Translate("Smartpage:Header.OfferNewspaperText.OfferNewspaper", "Tilbudsavis") 7935 </div> 7936 </div> 7937 </div> 7938 </a> 7939 </div> 7940 </div> 7941 </li> 7942 } 7943 7944 @helper RenderPriceBook(string link, string text, string icon = null) 7945 { 7946 <li class="menu__item menu__item--horizontal menu__item menu__item--icon menu__item--clean is-dropdown is-dropdown--no-icon dw-mod"> 7947 <div class="header-menu__link header-menu__link--icon dw-mod"> 7948 <div class="custom__header__icon"> 7949 <a href="@link"> 7950 @if (!string.IsNullOrEmpty(icon)) 7951 { 7952 <div class="custom__header__icon__icon custom__header__icon__price__book @icon"></div> 7953 } 7954 <div class="custom__header__icon__text"> 7955 <div> 7956 <div class="custom__header__icon__text"> 7957 @text 7958 </div> 7959 </div> 7960 </div> 7961 </a> 7962 </div> 7963 </div> 7964 </li> 7965 } 7966 7967 @helper RenderOfferNewspaperIcon() 7968 { 7969 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#ffffff" height="40px" width="54px" version="1.1" viewBox="0 0 465 465" xml:space="preserve"> 7970 <g> 7971 <path d="M371.957,60.634h-26.884V9.5c0-2.925-1.348-5.688-3.653-7.488c-2.307-1.801-5.316-2.438-8.15-1.729L90.745,60.912 l0.003,0.012c-4.136,1.028-7.205,4.755-7.205,9.209V455.5c0,5.247,4.253,9.5,9.5,9.5h278.915c5.247,0,9.5-4.253,9.5-9.5V70.134 C381.457,64.887,377.205,60.634,371.957,60.634z M326.074,60.634H170.201l155.873-38.966V60.634z M362.457,446H102.542V79.634 h259.915V446z" /> 7972 <path d="M127.632,156.409h209.735c5.247,0,9.5-4.253,9.5-9.5v-43.245c0-5.247-4.253-9.5-9.5-9.5H127.632 c-5.247,0-9.5,4.253-9.5,9.5v43.245C118.132,152.156,122.385,156.409,127.632,156.409z M137.132,113.164h190.735v24.245H137.132 V113.164z" /> 7973 <path d="M337.368,175.123H250.22c-5.247,0-9.5,4.253-9.5,9.5v135.358c0,5.247,4.253,9.5,9.5,9.5h87.147c5.247,0,9.5-4.253,9.5-9.5 V184.623C346.868,179.376,342.615,175.123,337.368,175.123z M327.868,310.481H259.72V194.123h68.147V310.481z" /> 7974 <path d="M127.632,194.123h87.147c5.247,0,9.5-4.253,9.5-9.5s-4.253-9.5-9.5-9.5h-87.147c-5.247,0-9.5,4.253-9.5,9.5 S122.385,194.123,127.632,194.123z" /> 7975 <path d="M127.632,227.794h87.147c5.247,0,9.5-4.253,9.5-9.5s-4.253-9.5-9.5-9.5h-87.147c-5.247,0-9.5,4.253-9.5,9.5 S122.385,227.794,127.632,227.794z" /> 7976 <path d="M127.632,261.465h87.147c5.247,0,9.5-4.253,9.5-9.5c0-5.247-4.253-9.5-9.5-9.5h-87.147c-5.247,0-9.5,4.253-9.5,9.5 C118.132,257.212,122.385,261.465,127.632,261.465z" /> 7977 <path d="M127.632,295.137h87.147c5.247,0,9.5-4.253,9.5-9.5s-4.253-9.5-9.5-9.5h-87.147c-5.247,0-9.5,4.253-9.5,9.5 S122.385,295.137,127.632,295.137z" /> 7978 <path d="M127.632,328.808h87.147c5.247,0,9.5-4.253,9.5-9.5s-4.253-9.5-9.5-9.5h-87.147c-5.247,0-9.5,4.253-9.5,9.5 S122.385,328.808,127.632,328.808z" /> 7979 <path d="M127.632,362.479h209.735c5.247,0,9.5-4.253,9.5-9.5s-4.253-9.5-9.5-9.5H127.632c-5.247,0-9.5,4.253-9.5,9.5 S122.385,362.479,127.632,362.479z" /> 7980 <path d="M127.632,396.15h209.735c5.247,0,9.5-4.253,9.5-9.5s-4.253-9.5-9.5-9.5H127.632c-5.247,0-9.5,4.253-9.5,9.5 S122.385,396.15,127.632,396.15z" /> 7981 <path d="M127.632,429.822h209.735c5.247,0,9.5-4.253,9.5-9.5s-4.253-9.5-9.5-9.5H127.632c-5.247,0-9.5,4.253-9.5,9.5 S122.385,429.822,127.632,429.822z" /> 7982 </g> 7983 </svg> 7984 } 7985 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 7986 @using Dynamicweb.Rapido.Blocks 7987 @using Smartpage.PhilipsonWine.LiveShopper.Models; 7988 7989 @{ 7990 if (Pageview.AreaSettings.GetItem("Custom").GetBoolean("ActivateLiveshopper")) 7991 { 7992 var upcomingEvent = Dynamicweb.Context.Current.Application["SpLiveShopperEvent"] as Event; 7993 Block masterDesktopActionsLiveshoppingBlock = new Block 7994 { 7995 Id = "MasterDesktopActionsLiveshopping", 7996 SortId = 10, 7997 Template = RenderLiveshoppingIcon(upcomingEvent) 7998 }; 7999 8000 BlocksPage.GetBlockPage("Master").Add("MasterDesktopActionsMenu", masterDesktopActionsLiveshoppingBlock); 8001 } 8002 } 8003 8004 @helper RenderLiveshoppingIcon(Event upcomingEvent) 8005 { 8006 DateTime now = DateTime.Now; 8007 bool isEventLive = upcomingEvent != null && now > upcomingEvent.Start && now < upcomingEvent.End; 8008 8009 <li class="menu__item menu__item--horizontal menu__item menu__item--icon menu__item--clean is-dropdown is-dropdown--no-icon dw-mod"> 8010 <div class="header-menu__link header-menu__link--icon dw-mod"> 8011 <div class="custom__header__icon"> 8012 <a href="/Default.aspx?ID=@GetPageIdByNavigationTag("LiveshoppingPage")"> 8013 <div class="custom__header__icon__icon liveshopping-icon"> 8014 @if (isEventLive) 8015 { 8016 @RenderLiveshoppingGreenIcon() 8017 } 8018 else 8019 { 8020 @RenderLiveshoppingWhiteIcon() 8021 } 8022 </div> 8023 <div class="custom__header__icon__text"> 8024 <div> 8025 @if (isEventLive) 8026 { 8027 <div class="pulsating-circle"></div> 8028 } 8029 <div class="custom__header__icon__text"> 8030 @Translate("Smartpage:Header.LiveshoppingText.Liveshopping", "Liveshopping") 8031 </div> 8032 </div> 8033 @if (isEventLive) 8034 { 8035 <div class="custom__header__icon__text__subtext"> 8036 @Translate("Smartpage:Header.LiveshoppingSubtextText.WeAreLive", "Vi sender nu!") 8037 </div> 8038 } 8039 else if (upcomingEvent != null) 8040 { 8041 TimeSpan timeDifference = now - upcomingEvent.Start; 8042 8043 double daysDifference = Math.Abs((timeDifference).Days); 8044 double hoursDifference = Math.Abs((timeDifference).TotalHours); 8045 double minutesDifference = Math.Abs((timeDifference).TotalMinutes); 8046 double secondsDifference = Math.Abs((timeDifference).TotalSeconds); 8047 8048 string daysText = daysDifference > 1 ? Translate("Smartpage.LiveshoppingCountdown.Days", "dage") : Translate("Smartpage.LiveshoppingCountdown.Day", "dag"); 8049 string hoursText = hoursDifference > 1 ? Translate("Smartpage.LiveshoppingCountdown.Hours", "timer") : Translate("Smartpage.LiveshoppingCountdown.Hour", "time"); 8050 string minutesText = Translate("Smartpage.LiveshoppingCountdown.Minutes", "min"); 8051 string secondsText = Translate("Smartpage.LiveshoppingCountdown.Seconds", "sek"); 8052 8053 <div class="u-flex js-countdown custom__header__icon__text__subtext" data-countdown-seconds="@secondsDifference"> 8054 <div><span class="js-days u-bold"></span>&nbsp;@daysText</div>&nbsp; 8055 <div><span class="js-hours u-bold"></span>&nbsp;@hoursText</div>&nbsp; 8056 <div><span class="js-minutes u-bold"></span>&nbsp;@minutesText</div>&nbsp; 8057 <div><span class="js-seconds u-bold"></span>&nbsp;@secondsText</div> 8058 </div> 8059 } 8060 </div> 8061 </a> 8062 </div> 8063 </div> 8064 </li> 8065 } 8066 8067 @helper RenderLiveshoppingGreenIcon() 8068 { 8069 <svg width="54px" height="40px" viewBox="0 0 54 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 8070 <title>live-active</title> 8071 <defs> 8072 <path d="M32.0214799,18.4559033 C32.8126585,18.452044 33.5016486,17.9130626 33.6984183,17.1440525 L35.7269729,9.64381814 C35.7549923,9.51994021 35.7251134,9.38999772 35.6458307,9.29097171 C35.5633361,9.20212396 35.4508359,9.14728857 35.3302637,9.13715272 L20.291955,9.13715272 L19.264154,5.38251895 C19.2316971,5.17420385 19.0397451,5.02975734 18.8313957,5.05681456 L16.3790846,5.05681456 L16.3790846,5.88010876 L18.5699235,5.88010876 L19.570677,9.63474252 L21.5992316,17.1440525 L21.6533264,17.2887958 L22.3565586,19.8582558 C21.6927986,20.2132651 21.2848056,20.9131054 21.3017102,21.6677388 L21.3017102,22.0839025 L21.3468033,22.0839025 C21.527725,23.0043143 22.3323005,23.6676401 23.2671683,23.6671945 C24.3740406,23.6721779 25.2767896,22.7784417 25.2867211,21.6676964 C25.275395,21.2430932 25.133692,20.8323155 24.8810102,20.4915557 L30.4076803,20.4915557 C30.1582103,20.8334181 30.0197192,21.2440686 30.0109711,21.6676964 C30.0209025,22.7784417 30.9236093,23.6721779 32.0305239,23.6671945 C32.9653917,23.6675977 33.7699672,23.0042719 33.9508889,22.0839025 L33.9959819,22.0839025 L33.9959819,21.6677388 C34.0059557,20.5734908 33.1300427,19.678355 32.0396524,19.6683464 C32.033609,19.668304 32.0275656,19.6682615 32.0215222,19.6682615 L23.2671683,19.6682615 L23.1319313,19.6682615 L22.7893169,18.3835528 C22.943318,18.4348258 23.1049262,18.459296 23.2671683,18.4559457 L32.0214799,18.4559457 L32.0214799,18.4559033 Z M32.3613634,20.6893079 C32.9780335,20.6752928 33.489321,21.1619997 33.503348,21.7763955 C33.5036677,21.7904106 33.5037077,21.8044257 33.5035079,21.8184408 C33.5036677,22.4184631 33.022872,22.908833 32.4207884,22.9226491 L32.4122763,22.9141683 C31.7956062,22.9281834 31.2843187,22.4414766 31.2702916,21.8270808 C31.2561847,21.2126851 31.7446932,20.7032832 32.3613634,20.6893079 Z M23.4694133,20.6891477 C24.086042,20.698581 24.578266,21.2040784 24.5689546,21.818238 C24.57395,22.4231632 24.0856424,22.9176353 23.4782851,22.9226107 C23.4638984,22.9227301 23.4494718,22.9225709 23.4350851,22.922133 L23.4350851,22.913655 C22.8183365,22.9042217 22.3260725,22.398565 22.3355837,21.7843259 C22.3450949,21.1700867 22.8527046,20.6796746 23.4694133,20.6891477 Z" id="path-1"></path> 8073 <filter x="-76.0%" y="-79.4%" width="252.1%" height="258.7%" filterUnits="objectBoundingBox" id="filter-2"> 8074 <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> 8075 <feGaussianBlur stdDeviation="5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> 8076 <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix> 8077 </filter> 8078 </defs> 8079 <g id="Header" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 8080 <g transform="translate(-1232.000000, -615.000000)" id="Header---2022---Dec-Copy-2"> 8081 <g transform="translate(-1.000000, 496.000000)"> 8082 <g id="Live" transform="translate(1192.000000, 0.000000)"> 8083 <g id="live-active" transform="translate(41.000000, 125.000000)"> 8084 <g id="Shape"> 8085 <use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use> 8086 <use fill="#50A87D" fill-rule="evenodd" xlink:href="#path-1"></use> 8087 </g> 8088 <path d="M10.3647541,23.4047666 C10.5829316,23.6197707 10.8690661,23.7272727 11.1550516,23.7272727 C11.4410371,23.7272727 11.7271716,23.6197707 11.9453492,23.4047666 C12.3818533,22.9744647 12.3818533,22.27717 11.9453492,21.8470149 C9.90470344,19.8360511 8.78073134,17.1623049 8.78073134,14.3182002 C8.78073134,11.4740955 9.90470344,8.80034925 11.9453492,6.78938542 C12.3818533,6.35908351 12.3818533,5.66178882 11.9453492,5.23178063 C11.508994,4.80162559 10.8012582,4.80147873 10.3647541,5.23163377 C7.90176191,7.65865402 6.54545455,10.8857715 6.54545455,14.3182002 C6.54545455,17.7506289 7.90176191,20.9775995 10.3647541,23.4047666 Z" id="Path" fill="#50A87D" fill-rule="nonzero"></path> 8089 <path d="M42.0546508,23.4047666 C42.2728284,23.6197707 42.5589629,23.7272727 42.8449484,23.7272727 C43.1309339,23.7272727 43.4170684,23.6197707 43.6352459,23.4047666 C46.0982381,20.9775995 47.4545455,17.7506289 47.4545455,14.3182002 C47.4545455,10.8857714 46.0980891,7.65865401 43.6352459,5.23163376 C43.1987418,4.80162558 42.491006,4.80147872 42.0546508,5.23178062 C41.6181467,5.66193567 41.6181467,6.35923036 42.0546508,6.78938541 C44.0952966,8.80020238 45.2192687,11.4739486 45.2192687,14.3182002 C45.2192687,17.162158 44.0952966,19.8359043 42.0546508,21.8470149 C41.6181467,22.27717 41.6181467,22.9744647 42.0546508,23.4047666 Z" id="Path" fill="#50A87D" fill-rule="nonzero"></path> 8090 <path d="M6.26235997,27 C6.54414929,27 6.82608544,26.8929969 7.04106176,26.6789908 C7.47116123,26.2506862 7.47116123,25.5566281 7.04106176,25.1284697 C3.92082148,22.0224574 2.20247936,17.8926071 2.20247936,13.5000731 C2.20247936,9.10739287 3.92082148,4.97754257 7.04106176,1.87153028 C7.47116123,1.44322568 7.47116123,0.749167592 7.04106176,0.321009177 C6.61096228,-0.107003059 5.91361082,-0.107003059 5.48365819,0.321009177 C1.94741525,3.84129287 0,8.52179963 0,13.5000731 C0,18.4783466 1.94741525,23.1587071 5.48365819,26.6789908 C5.69863451,26.8928508 5.98042382,27 6.26235997,27 Z" id="Path" fill="#8EFFC8" fill-rule="nonzero"></path> 8091 <path d="M46.1411428,25.1284697 C45.7105281,25.5567743 45.7105281,26.2508324 46.1411428,26.6789908 C46.3563767,26.8929969 46.6386506,27 46.9207775,27 C47.2029043,27 47.4851782,26.8929969 47.7004121,26.6789908 C55.0089536,19.4119921 55.0089536,7.58786173 47.7004121,0.321009177 C47.2697974,-0.107003059 46.5716105,-0.107003059 46.1411428,0.321009177 C45.7105281,0.749313771 45.7105281,1.44337186 46.1411428,1.87153028 C52.5897781,8.28338161 52.5897781,18.7166184 46.1411428,25.1284697 Z" id="Path" fill="#8EFFC8" fill-rule="nonzero"></path> 8092 </g> 8093 </g> 8094 </g> 8095 </g> 8096 </g> 8097 </svg> 8098 } 8099 8100 @helper RenderLiveshoppingWhiteIcon() 8101 { 8102 <svg width="54px" height="40px" viewBox="0 0 54 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 8103 <title>live</title> 8104 <defs> 8105 <path d="M32.0214799,18.4559033 C32.8126585,18.452044 33.5016486,17.9130626 33.6984183,17.1440525 L35.7269729,9.64381814 C35.7549923,9.51994021 35.7251134,9.38999772 35.6458307,9.29097171 C35.5633361,9.20212396 35.4508359,9.14728857 35.3302637,9.13715272 L20.291955,9.13715272 L19.264154,5.38251895 C19.2316971,5.17420385 19.0397451,5.02975734 18.8313957,5.05681456 L16.3790846,5.05681456 L16.3790846,5.88010876 L18.5699235,5.88010876 L19.570677,9.63474252 L21.5992316,17.1440525 L21.6533264,17.2887958 L22.3565586,19.8582558 C21.6927986,20.2132651 21.2848056,20.9131054 21.3017102,21.6677388 L21.3017102,22.0839025 L21.3468033,22.0839025 C21.527725,23.0043143 22.3323005,23.6676401 23.2671683,23.6671945 C24.3740406,23.6721779 25.2767896,22.7784417 25.2867211,21.6676964 C25.275395,21.2430932 25.133692,20.8323155 24.8810102,20.4915557 L30.4076803,20.4915557 C30.1582103,20.8334181 30.0197192,21.2440686 30.0109711,21.6676964 C30.0209025,22.7784417 30.9236093,23.6721779 32.0305239,23.6671945 C32.9653917,23.6675977 33.7699672,23.0042719 33.9508889,22.0839025 L33.9959819,22.0839025 L33.9959819,21.6677388 C34.0059557,20.5734908 33.1300427,19.678355 32.0396524,19.6683464 C32.033609,19.668304 32.0275656,19.6682615 32.0215222,19.6682615 L23.2671683,19.6682615 L23.1319313,19.6682615 L22.7893169,18.3835528 C22.943318,18.4348258 23.1049262,18.459296 23.2671683,18.4559457 L32.0214799,18.4559457 L32.0214799,18.4559033 Z M32.3613634,20.6893079 C32.9780335,20.6752928 33.489321,21.1619997 33.503348,21.7763955 C33.5036677,21.7904106 33.5037077,21.8044257 33.5035079,21.8184408 C33.5036677,22.4184631 33.022872,22.908833 32.4207884,22.9226491 L32.4122763,22.9141683 C31.7956062,22.9281834 31.2843187,22.4414766 31.2702916,21.8270808 C31.2561847,21.2126851 31.7446932,20.7032832 32.3613634,20.6893079 Z M23.4694133,20.6891477 C24.086042,20.698581 24.578266,21.2040784 24.5689546,21.818238 C24.57395,22.4231632 24.0856424,22.9176353 23.4782851,22.9226107 C23.4638984,22.9227301 23.4494718,22.9225709 23.4350851,22.922133 L23.4350851,22.913655 C22.8183365,22.9042217 22.3260725,22.398565 22.3355837,21.7843259 C22.3450949,21.1700867 22.8527046,20.6796746 23.4694133,20.6891477 Z" id="path-1"></path> 8106 <filter x="-76.0%" y="-79.4%" width="252.1%" height="258.7%" filterUnits="objectBoundingBox" id="filter-2"> 8107 <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> 8108 <feGaussianBlur stdDeviation="5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> 8109 <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix> 8110 </filter> 8111 </defs> 8112 <g id="Header" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 8113 <g transform="translate(-1232.000000, -59.000000)" id="Header---2022---Dec"> 8114 <g transform="translate(-1.000000, 0.000000)"> 8115 <g id="Live" transform="translate(1192.000000, 65.000000)"> 8116 <g id="live" transform="translate(41.000000, 0.000000)"> 8117 <g id="Shape"> 8118 <use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use> 8119 <use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use> 8120 </g> 8121 <path d="M10.3647541,23.4047666 C10.5829316,23.6197707 10.8690661,23.7272727 11.1550516,23.7272727 C11.4410371,23.7272727 11.7271716,23.6197707 11.9453492,23.4047666 C12.3818533,22.9744647 12.3818533,22.27717 11.9453492,21.8470149 C9.90470344,19.8360511 8.78073134,17.1623049 8.78073134,14.3182002 C8.78073134,11.4740955 9.90470344,8.80034925 11.9453492,6.78938542 C12.3818533,6.35908351 12.3818533,5.66178882 11.9453492,5.23178063 C11.508994,4.80162559 10.8012582,4.80147873 10.3647541,5.23163377 C7.90176191,7.65865402 6.54545455,10.8857715 6.54545455,14.3182002 C6.54545455,17.7506289 7.90176191,20.9775995 10.3647541,23.4047666 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path> 8122 <path d="M42.0546508,23.4047666 C42.2728284,23.6197707 42.5589629,23.7272727 42.8449484,23.7272727 C43.1309339,23.7272727 43.4170684,23.6197707 43.6352459,23.4047666 C46.0982381,20.9775995 47.4545455,17.7506289 47.4545455,14.3182002 C47.4545455,10.8857714 46.0980891,7.65865401 43.6352459,5.23163376 C43.1987418,4.80162558 42.491006,4.80147872 42.0546508,5.23178062 C41.6181467,5.66193567 41.6181467,6.35923036 42.0546508,6.78938541 C44.0952966,8.80020238 45.2192687,11.4739486 45.2192687,14.3182002 C45.2192687,17.162158 44.0952966,19.8359043 42.0546508,21.8470149 C41.6181467,22.27717 41.6181467,22.9744647 42.0546508,23.4047666 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path> 8123 <path d="M6.26235997,27 C6.54414929,27 6.82608544,26.8929969 7.04106176,26.6789908 C7.47116123,26.2506862 7.47116123,25.5566281 7.04106176,25.1284697 C3.92082148,22.0224574 2.20247936,17.8926071 2.20247936,13.5000731 C2.20247936,9.10739287 3.92082148,4.97754257 7.04106176,1.87153028 C7.47116123,1.44322568 7.47116123,0.749167592 7.04106176,0.321009177 C6.61096228,-0.107003059 5.91361082,-0.107003059 5.48365819,0.321009177 C1.94741525,3.84129287 0,8.52179963 0,13.5000731 C0,18.4783466 1.94741525,23.1587071 5.48365819,26.6789908 C5.69863451,26.8928508 5.98042382,27 6.26235997,27 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path> 8124 <path d="M46.1411428,25.1284697 C45.7105281,25.5567743 45.7105281,26.2508324 46.1411428,26.6789908 C46.3563767,26.8929969 46.6386506,27 46.9207775,27 C47.2029043,27 47.4851782,26.8929969 47.7004121,26.6789908 C55.0089536,19.4119921 55.0089536,7.58786173 47.7004121,0.321009177 C47.2697974,-0.107003059 46.5716105,-0.107003059 46.1411428,0.321009177 C45.7105281,0.749313771 45.7105281,1.44337186 46.1411428,1.87153028 C52.5897781,8.28338161 52.5897781,18.7166184 46.1411428,25.1284697 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path> 8125 </g> 8126 </g> 8127 </g> 8128 </g> 8129 </g> 8130 </svg> 8131 } 8132 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 8133 @using System 8134 @using System.Web 8135 8136 @helper RenderPromoBar(Dynamicweb.Frontend.ItemViewModel promoBarSettings, IList<Dynamicweb.Frontend.ItemViewModel> promoBarContent) 8137 { 8138 // CDN 8139 var cdnUrl = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetString("CDNUrl"); 8140 Func<string, string> buildImageUrl = (img) => 8141 { 8142 if (string.IsNullOrEmpty(img)) 8143 { 8144 return string.Empty; 8145 } 8146 8147 string imagePrefix = "/Admin/Public/GetImage.ashx?width=100&height=100&Compression=75&image="; 8148 bool useCdn = Pageview.AreaSettings.GetItem("Custom").GetBoolean("CDNActivate") && !string.IsNullOrWhiteSpace(cdnUrl); 8149 8150 return (useCdn ? cdnUrl : string.Empty) + imagePrefix + img; 8151 }; 8152 8153 Dictionary<string, string> extraAttributes = new Dictionary<string, string>(); 8154 string styles = ""; 8155 string promoBarBackgroundColor = promoBarSettings.GetRawValueString("PromoBarBackgroundColor"); 8156 string promoBarTextColor = promoBarSettings.GetRawValueString("PromoBarTextColor"); 8157 8158 if (!string.IsNullOrWhiteSpace(promoBarBackgroundColor)) 8159 { 8160 styles += $"background-color: {promoBarBackgroundColor};"; 8161 } 8162 8163 if (!string.IsNullOrWhiteSpace(promoBarTextColor)) 8164 { 8165 styles += $"color: {promoBarTextColor};"; 8166 } 8167 8168 if (!string.IsNullOrWhiteSpace(styles)) 8169 { 8170 extraAttributes.Add("style", HttpUtility.HtmlAttributeEncode(styles)); 8171 } 8172 8173 bool showArrows = promoBarContent.Count(item => !string.IsNullOrWhiteSpace(item.GetRawValueString("Text"))) > 1; 8174 8175 <div class="promo-bar promo-bar--hidden js-promo-bar" @Dynamicweb.Rapido.Blocks.Components.ComponentMethods.AddAttributes(extraAttributes)> 8176 <div class="promo-bar__nav"> 8177 @if (showArrows) 8178 { 8179 <button class="promo-bar__arrow js-promo-bar-prev" aria-label="Previous"> 8180 <i class="far fa-angle-left"></i> 8181 </button> 8182 } 8183 </div> 8184 <div class="promo-bar__content"> 8185 <div class="promo-bar__content__track js-promo-bar-track"> 8186 @foreach (var item in promoBarContent) 8187 { 8188 string icon = item.GetRawValueString("Icon"); 8189 string text = item.GetRawValueString("Text"); 8190 string link = item.GetRawValueString("Link"); 8191 8192 8193 if (!string.IsNullOrWhiteSpace(text)) 8194 { 8195 if (!string.IsNullOrWhiteSpace(link)) 8196 { 8197 <a href="@(HttpUtility.HtmlAttributeEncode(link))" class="promo-bar__content__slide js-promo-bar-slide"> 8198 @RenderInnerContent(icon, text, buildImageUrl) 8199 </a> 8200 } 8201 else 8202 { 8203 <div class="promo-bar__content__slide js-promo-bar-slide"> 8204 @RenderInnerContent(icon, text, buildImageUrl) 8205 </div> 8206 } 8207 } 8208 } 8209 </div> 8210 </div> 8211 <div class="promo-bar__nav promo-bar__nav--right"> 8212 @if (showArrows) 8213 { 8214 <button class="promo-bar__arrow js-promo-bar-next" aria-label="Next"> 8215 <i class="far fa-angle-right"></i> 8216 </button> 8217 } 8218 <button class="promo-bar__close js-promo-bar-close" aria-label="Close"> 8219 <i class="far fa-times"></i> 8220 </button> 8221 </div> 8222 </div> 8223 } 8224 8225 @helper RenderInnerContent(string icon, string text, Func<string, string> buildImageUrl) 8226 { 8227 if (!string.IsNullOrWhiteSpace(icon)) 8228 { 8229 <img src="@buildImageUrl(icon)" alt="@HttpUtility.HtmlAttributeEncode(text)" /> 8230 } 8231 <span>@HttpUtility.HtmlEncode(text)</span> 8232 } 8233 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 8234 @using Dynamicweb.Rapido.Blocks 8235 8236 @{ 8237 bool activateChainOrdersLink = Pageview.AreaSettings.GetItem("Custom").GetBoolean("ActivateChainOrdersLink"); 8238 var chainCustomerProducts = Smartpage.PhilipsonWine.ChainCustomer.ChainProductService.GetChainCustomerProducts(); 8239 if (activateChainOrdersLink && chainCustomerProducts.Any()) 8240 { 8241 Block masterDesktopActionsChainOrdersBlock = new Block 8242 { 8243 Id = "MasterDesktopActionsChainOrders", 8244 SortId = 10, 8245 Template = RenderChainOrdersAction() 8246 }; 8247 8248 BlocksPage.GetBlockPage("Master").Add("MasterDesktopActionsMenu", masterDesktopActionsChainOrdersBlock); 8249 } 8250 } 8251 8252 @helper RenderChainOrdersAction() 8253 { 8254 <li class="menu__item menu__item--horizontal menu__item menu__item--icon menu__item--clean is-dropdown is-dropdown--no-icon dw-mod"> 8255 <div class="header-menu__link header-menu__link--icon dw-mod"> 8256 <div class="custom__header__icon"> 8257 <a href="/Default.aspx?ID=@GetPageIdByNavigationTag("ChainOrdersPage")"> 8258 <div class="custom__header__icon__icon chain-order-icon"> 8259 <svg xmlns="http://www.w3.org/2000/svg" width="26.786" height="25" viewBox="0 0 26.786 25"> 8260 <path id="Path_6" data-name="Path 6" d="M5,30.321A2.679,2.679,0,1,1,7.679,33,2.679,2.679,0,0,1,5,30.321ZM7.679,13.357A2.679,2.679,0,1,0,5,10.679a2.679,2.679,0,0,0,2.679,2.679Zm0,9.821A2.679,2.679,0,1,0,5,20.5,2.679,2.679,0,0,0,7.679,23.179Zm8.929-10.714H30a1.786,1.786,0,0,0,0-3.571H16.607a1.786,1.786,0,1,0,0,3.571Zm0,9.821H30a1.786,1.786,0,1,0,0-3.571H16.607a1.786,1.786,0,1,0,0,3.571Zm0,9.821H30a1.786,1.786,0,0,0,0-3.571H16.607a1.786,1.786,0,1,0,0,3.571Z" transform="translate(-5 -8)" fill="#fff" /> 8261 </svg> 8262 </div> 8263 <div class="custom__header__icon__text"> 8264 <div> 8265 <div class="custom__header__icon__text"> 8266 @Translate("Smartpage:Header.ChainOrdersText.ChainOrders", "Rammeordrer") 8267 </div> 8268 </div> 8269 </div> 8270 </a> 8271 </div> 8272 </div> 8273 </li> 8274 } 8275 8276 8277 @helper RenderDesktopTools() 8278 { 8279 if (Model.ID != GetPageIdByNavigationTag("CartPage") && Model.ID != GetPageIdByNavigationTag("CheckoutPage")) 8280 { 8281 List<Block> subBlocks = headerBlocksPage.GetBlockListById("MasterDesktopTools").OrderBy(item => item.SortId).ToList(); 8282 8283 <div class="tools-navigation dw-mod"> 8284 <div class="center-container grid top-container__center-container dw-mod"> 8285 @RenderBlockList(subBlocks) 8286 </div> 8287 </div> 8288 } 8289 } 8290 8291 @helper RenderDesktopToolsText() 8292 { 8293 string toolsText = Model.Area.Item.GetItem("Layout").GetItem("Header").GetString("ToolsText"); 8294 if (!string.IsNullOrEmpty(toolsText)) 8295 { 8296 <div class="u-margin-top u-margin-bottom">@toolsText</div> 8297 } 8298 } 8299 8300 @helper RenderDesktopToolsNavigation() 8301 { 8302 bool renderPagesInToolBar = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("RenderPagesInToolBar"); 8303 8304 if (renderPagesInToolBar) 8305 { 8306 @RenderNavigation(new 8307 { 8308 id = "topToolsNavigation", 8309 cssclass = "menu menu-tools dw-mod dwnavigation", 8310 template = "TopMenu.xslt" 8311 }) 8312 } 8313 } 8314 8315 @helper RenderDesktopNavigation() 8316 { 8317 List<Block> subBlocks = headerBlocksPage.GetBlockListById("MasterDesktopNavigation").OrderBy(item => item.SortId).ToList(); 8318 string topLayout = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("TopLayout").SelectedValue : "normal"; 8319 string alignClass = topLayout == "two-lines-centered" ? "grid--justify-center" : ""; 8320 string menuType = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("NavigationMegaMenu") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetRawValueString("NavigationMegaMenu") : "dropdown"; 8321 bool isSidemenu = menuType == "sidemenu"; 8322 if (isSidemenu) 8323 { 8324 <div class="sidemenu__modal-overlay js-sidemenu-overlay"></div> 8325 } 8326 8327 <nav class="main-navigation @(isSidemenu ? "sidemenu-navigation js-sidemenu-navigation" : "") js-main-navigation dw-mod"> 8328 @if (isSidemenu) 8329 { 8330 <div class="navigation-header"> 8331 <div class="navigation-header__previous js-navigation-previous">@RenderPreviousButton()</div> 8332 <div class="navigation-header__mid"> 8333 <div class="js-navigation-logo"> 8334 @RenderSidemenuLogo() 8335 </div> 8336 <h2 class="js-navigation-active-title"></h2> 8337 </div> 8338 <div class="navigation-header__close js-sidemenu-close">@RenderCloseButton()</div> 8339 </div> 8340 <div class="navigation-container js-navigation-container"> 8341 @RenderBlockList(subBlocks) 8342 </div> 8343 <div class="sidemenu-sub-navigation js-sidemenu-sub-navigation"> 8344 <div class="navigation-header"> 8345 <h2 class="js-sub-navigation-title"></h2> 8346 <div class="navigation-header__close js-sidemenu-close">@RenderCloseButton()</div> 8347 </div> 8348 <div class="navigation-container js-navigation-container"> 8349 <div class="js-sub-navigation-items"></div> 8350 </div> 8351 </div> 8352 } 8353 else 8354 { 8355 <div class="center-container top-container__center-container grid @alignClass dw-mod"> 8356 @RenderBlockList(subBlocks) 8357 </div> 8358 } 8359 </nav> 8360 } 8361 8362 @helper RenderDesktopExtra() 8363 { 8364 List<Block> subBlocks = headerBlocksPage.GetBlockListById("MasterDesktopExtra").OrderBy(item => item.SortId).ToList(); 8365 string menuType = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("NavigationMegaMenu") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetRawValueString("NavigationMegaMenu") : "dropdown"; 8366 8367 if (subBlocks.Count > 0) 8368 { 8369 <div class="header header-top dw-mod custom__header__top js-header-top @(Model.ID == GetPageIdByNavigationTag("CartPage") || Model.ID == GetPageIdByNavigationTag("CheckoutPage") ? "is-cart-page" : "")"> 8370 <div class="center-container top-container__center-container grid--justify-space-between grid grid--align-center dw-mod"> 8371 @RenderBlockList(subBlocks) 8372 </div> 8373 </div> 8374 } 8375 } 8376 8377 8378 @{ 8379 if (Pageview.Page.NavigationTag == "CartPage" && Pageview.Device.ToString() == "Tablet") 8380 { 8381 Block mobileCheckoutUsp = new Block 8382 { 8383 Id = "MobileCheckoutUsp", 8384 SortId = 50, 8385 Template = RenderMobileCheckoutUsp() 8386 }; 8387 mobileHeaderBlocksPage.Add(MasterBlockId.MasterHeader, mobileCheckoutUsp); 8388 } 8389 } 8390 8391 @helper RenderPreviousButton() 8392 { 8393 <svg xmlns="http://www.w3.org/2000/svg" width="27.663" height="19.992" viewBox="0 0 27.663 19.992"> 8394 <path id="Path_122" data-name="Path 122" d="M11.946,3.067a1.139,1.139,0,0,0-1.61,0L1.346,12.057a.949.949,0,0,0,0,1.344l8.991,8.991a1.139,1.139,0,0,0,1.611-1.611L5.034,13.868H27.592a1.139,1.139,0,1,0,0-2.278H5.034l6.914-6.912a1.139,1.139,0,0,0,0-1.611Z" transform="translate(-1.067 -2.734)" fill="#3b3d3e" fill-rule="evenodd" /> 8395 </svg> 8396 } 8397 8398 @helper RenderSidemenuLogo() 8399 { 8400 <svg class="sidemenu-logo" xmlns="http://www.w3.org/2000/svg" width="299.404" height="61.255" viewBox="0 0 299.404 61.255"> 8401 <g id="philipson-wine-logo-mobil" transform="translate(0 0)"> 8402 <path id="Path_1" data-name="Path 1" d="M76.936,67.213c2.668-.339,3.176-.931,3.176-4.574V42.646c0-2.2-1.059-2.88-2.965-2.372v-.508L85.2,37.181V51.288c2.033-2.033,4.32-4.025,7.2-4.025,3.176,0,5.337,2.118,5.337,5.8v9.573c0,3.558.466,4.277,2.965,4.574v.339H89.515v-.339c2.711-.339,3.092-.974,3.092-4.574V53.955c0-2.584-.974-3.812-3.092-3.812-1.652,0-3.007.974-4.32,2.161V62.639c0,3.6.466,4.32,2.88,4.574v.339H76.936Z" transform="translate(-50.459 -24.385)" fill="#3b3d3e" /> 8403 <path id="Path_2" data-name="Path 2" d="M150.708,67.539c2.753-.339,3.3-1.016,3.3-4.574V52.376c0-1.95-1.1-2.33-3.135-1.736v-.51l8.26-2.71V62.965c0,3.515.551,4.277,2.923,4.574v.339H150.708Zm2.8-27.066a2.844,2.844,0,0,1,3.008-2.8,2.8,2.8,0,1,1,0,5.591A2.871,2.871,0,0,1,153.5,40.473Z" transform="translate(-98.843 -24.711)" fill="#3b3d3e" /> 8404 <path id="Path_3" data-name="Path 3" d="M190.266,67.213c2.711-.339,3.177-1.016,3.177-4.574V42.731c0-2.923-1.313-2.88-3.219-2.372v-.508l8.3-2.669V62.639c0,3.515.551,4.235,2.965,4.574v.339H190.266Z" transform="translate(-124.76 -24.385)" fill="#3b3d3e" /> 8405 <path id="Path_4" data-name="Path 4" d="M230.106,67.539c2.753-.339,3.3-1.016,3.3-4.574V52.376c0-1.95-1.1-2.33-3.135-1.736v-.51l8.26-2.71V62.965c0,3.515.551,4.277,2.923,4.574v.339H230.106Zm2.8-27.066a2.844,2.844,0,0,1,3.008-2.8,2.8,2.8,0,1,1,0,5.591A2.871,2.871,0,0,1,232.9,40.473Z" transform="translate(-150.917 -24.711)" fill="#3b3d3e" /> 8406 <path id="Path_5" data-name="Path 5" d="M265.189,96.478c2.8-.338,3.262-1.059,3.262-4.617V71.911c0-2.921-1.1-3.218-2.923-2.753V68.65l8.048-2.541V70.6c2.118-2.667,3.431-4.363,6.524-4.363,5.167,0,8.26,4.279,8.26,9.912,0,6.481-4.872,10.886-10.081,10.886-2.372,0-3.177-.762-4.7-2.076V91.9c.043,3.432.932,4.277,3.516,4.574v.339h-11.9Zm17.536-19.1c0-4.151-1.525-7.963-5-7.963-1.906,0-3.008,1.185-4.151,2.5v8.556c0,3.474,1.906,5.21,4.405,5.21,3.346,0,4.744-3.94,4.744-8.3Z" transform="translate(-173.926 -43.358)" fill="#3b3d3e" /> 8407 <path id="Path_6" data-name="Path 6" d="M346.224,86.056a1.281,1.281,0,0,0-.677-.128.839.839,0,0,0-.889.679h-.424V79.66h.381c.551,3.43,3.262,6.31,6.4,6.31a2.973,2.973,0,0,0,3.219-3.007c0-1.821-1.185-2.627-4.7-4.32-4.024-1.864-5.633-3.177-5.633-6.438,0-3.56,3.007-5.973,6.777-5.973a9.222,9.222,0,0,1,4.024.931,1.442,1.442,0,0,0,.678.128.86.86,0,0,0,.762-.551h.423l.339,6.227h-.466c-.677-3.263-3.007-5.592-5.845-5.592-1.78,0-3.219.848-3.219,2.541,0,1.821,1.312,2.5,4.955,4.322,4.194,1.948,6.057,3.346,6.057,6.65,0,4.023-3.685,6.227-7.328,6.227A13.456,13.456,0,0,1,346.224,86.056Z" transform="translate(-225.547 -43.439)" fill="#3b3d3e" /> 8408 <path id="Path_7" data-name="Path 7" d="M394.115,76.938a10.314,10.314,0,0,1,10.632-10.463c5.973,0,10.631,4.109,10.631,10.335a10.338,10.338,0,0,1-10.631,10.463C398.774,87.274,394.115,83.123,394.115,76.938Zm15.673,1.4c0-4.574-1.652-10.673-5.761-10.673-2.922,0-4.32,3.43-4.32,7.709,0,4.617,1.652,10.716,5.76,10.716,2.923,0,4.321-3.515,4.321-7.751Z" transform="translate(-258.483 -43.598)" fill="#3b3d3e" /> 8409 <path id="Path_8" data-name="Path 8" d="M460.1,86.186c2.753-.339,3.176-1.1,3.176-4.574V71.53c0-2.838-1.059-2.88-3.008-2.33v-.508l8.133-2.584V70.26c2.076-2.033,4.321-4.025,7.2-4.025,3.219,0,5.336,2.118,5.336,5.8v9.573c0,3.558.466,4.277,3.008,4.574v.339H472.763v-.339c2.668-.339,3.049-.974,3.049-4.574V72.927c0-2.584-.974-3.812-3.092-3.812-1.652,0-3.008.974-4.321,2.161V81.612c0,3.515.467,4.277,2.88,4.574v.339H460.1Z" transform="translate(-301.759 -43.358)" fill="#3b3d3e" /> 8410 <path id="Path_9" data-name="Path 9" d="M40.509,85.5a9.615,9.615,0,0,1-2.125.487.61.61,0,0,0,.139.01,5.79,5.79,0,0,0,3.456-1.162A7.613,7.613,0,0,1,40.509,85.5Z" transform="translate(-25.174 -55.64)" fill="#3b3d3e" /> 8411 <path id="Path_10" data-name="Path 10" d="M23.817,45.21a8.136,8.136,0,0,0-2.94-2.731,10.692,10.692,0,0,0-3.853-1.347,36.6,36.6,0,0,0-4.7-.268H0v.423c.328.04.56.069.9.119s.685.139,1,.2c1.6.407,1.986,1.261,1.986,4.092V65.053c0,3.774-.675,4.152-3.854,4.579v.338H13.924v-.407a5.839,5.839,0,0,1-2.572-.6,3.325,3.325,0,0,1-1.241-1.053,2.923,2.923,0,0,1-.447-1.52c-.02-.616-.05-1.361-.079-2.215,0-.457,0-.874-.02-1.261s-.02-.814-.02-1.271V57.873h2.175c.824,0,1.678-.04,2.552-.1S16,57.6,16.864,57.466a13.006,13.006,0,0,0,2.413-.6A11.224,11.224,0,0,0,21.4,55.8a7.662,7.662,0,0,0,3.1-3.715,7.255,7.255,0,0,0,.477-2.692A7.446,7.446,0,0,0,23.817,45.21Zm-4.539,8.542A7.075,7.075,0,0,1,16.8,56a5.79,5.79,0,0,1-3.456,1.162.61.61,0,0,1-.139-.01,5.475,5.475,0,0,1-.566.06c-.963.07-2,.1-3.1.1V52.162c0-1.281.01-2.592.02-3.933,0-.159,0-.318.01-.477V42.12c.055-.028.113-.069.172-.1a1.338,1.338,0,0,1,.215-.073c3.248-.717,7.6.2,9.495,3.1a7.408,7.408,0,0,1,1.182,4.142,8.017,8.017,0,0,1-1.361,4.559Z" transform="translate(0 -26.8)" fill="#3b3d3e" /> 8412 <path id="Path_11" data-name="Path 11" d="M723.748,37.943s-1.373,1.04-2.23.735a4.114,4.114,0,0,0-2.712.511c-1.068.546-1.569.953-2.212,1.22a8.238,8.238,0,0,1-1.575.223s.306-.115.346-.336a1.225,1.225,0,0,1,.256-.466,8.021,8.021,0,0,0-1.981-.076,2.99,2.99,0,0,1-2.262.215.777.777,0,0,0,.411-.381c.105-.266.381-.842.381-.842-.406-.587-1.544-.281-2.276-.642a.76.76,0,0,0,.517-.647,3.83,3.83,0,0,0-1.394-.482c-.727-.075-1.424-.943-1.71-.938a.777.777,0,0,0,.411-.381,5.369,5.369,0,0,1,1.515-1.434,3.136,3.136,0,0,0-.933-.512c-.486-.146-.712-.471-1-.467a1.575,1.575,0,0,0,.522-.361,1.548,1.548,0,0,1,.411-.381,5.648,5.648,0,0,1-1.554-.853,1,1,0,0,0,.477-.426,1.508,1.508,0,0,1-1.008-1.038c-.346-.918-.652-.8-.652-.8a4.931,4.931,0,0,0,1.088-.657,3.019,3.019,0,0,1,.893-.521s-.812-1.174-.988-1.149a4.205,4.205,0,0,0,.852-.3c.2-.135-1.113-.772-1.429-1.229s-.9-1.3-1.078-1.279a2.756,2.756,0,0,0,1.133-.591,1.4,1.4,0,0,1,1.093-.371,1.849,1.849,0,0,0-.561-.672c-.311-.171-.255-.787-.456-.938a1.336,1.336,0,0,0,.7-.1c.371-.16.742-.321.9-.235a1.372,1.372,0,0,0-.251-.5c-.226-.326-.1-.7-.321-.742a1.1,1.1,0,0,0,.547-.185l.261-.18a3.462,3.462,0,0,1-.035-2,.791.791,0,0,0-.125-.878,1.451,1.451,0,0,0,.817.206,10.257,10.257,0,0,1,2.888.412,1.989,1.989,0,0,1-.035-.747,1.011,1.011,0,0,0-.01-.572s.6.451.8.316l-.361-.522c-.045-.065.742-.321.918-.346a1.1,1.1,0,0,1-.125-.878.9.9,0,0,0-.035-.747,2.169,2.169,0,0,0,.506.035c.176-.025.547-.185.7-.1a1.355,1.355,0,0,1-.215-1.008c.146-.486.186-.707.1-.837a2.55,2.55,0,0,0,1.013.07,7.275,7.275,0,0,0,.482-1.394c0-.286.617-1.2.547-1.439,0,0,1.454,1.4,2.025,1.395,0,0,.356-1.018.266-1.148a6.343,6.343,0,0,1,2.056.6s-.336-.346-.3-.567-.316-.456-.316-.456l.722-.21a4.1,4.1,0,0,1,.442-2.427.975.975,0,0,0-.1-.416,2.393,2.393,0,0,0,.953.4,1.767,1.767,0,0,1,.707.186,1.784,1.784,0,0,1,.291-.973,4.279,4.279,0,0,0,.672-1.815s.541.782,1.243.682a3.661,3.661,0,0,0,.462-1.284s.205.436.491.431A7.336,7.336,0,0,0,726.508.384,1.362,1.362,0,0,0,727,.815a13.146,13.146,0,0,1,1.509,2.041c.226.326,1.509.788,1.985,1.615,0,0,.04-.221.411-.381s.346-.336.346-.336a2.456,2.456,0,0,0,.321.742,1.988,1.988,0,0,1,.441,1.334,1.914,1.914,0,0,1,.772,1.394.926.926,0,0,1,.587-.406,1.092,1.092,0,0,0,.717-.5,10.167,10.167,0,0,1,.265,1.359,6.652,6.652,0,0,0,.075,1.78l.366-.446a1.849,1.849,0,0,0,.406,1.84,7.759,7.759,0,0,1,1.013-1.183c.326-.226.762-.431.933-.742a1.382,1.382,0,0,0,.341.632,2.554,2.554,0,0,0,.4.3s.406-.667.757-.717c0,0,.18.261.246.216A3.522,3.522,0,0,1,740.7,8.5c.351-.05.431-.491.431-.491a3.231,3.231,0,0,0,.486,1.4,4.558,4.558,0,0,1,.556,1.64,4.857,4.857,0,0,1,1.219-.747,1.62,1.62,0,0,0,.893-.521,1.411,1.411,0,0,0,.3.853,1.412,1.412,0,0,1,.3.853s.186-.707.557-.867a1.343,1.343,0,0,0,.522-.361s-.015.4.14.481.14.481.14.481a2.3,2.3,0,0,1,1.665-.381.982.982,0,0,0,.7-.1,2.565,2.565,0,0,0-.176,1.279,3,3,0,0,1,.02,1.143,6.838,6.838,0,0,0,1.154-.7.836.836,0,0,0,.035.747,2.191,2.191,0,0,1,.3.567,5.011,5.011,0,0,1,1.62-.446,1.339,1.339,0,0,0,.592-.12,5.5,5.5,0,0,0-.176,1.279c.05.351.075.527-.01.682s.918-.346.918-.346l.07.241a1.542,1.542,0,0,1,.7-.386c.351-.05.837.1,1.183-.24,0,0-.341.622-.161.882s1.63.126,1.87.056.983-.391,1.289-.506a2.092,2.092,0,0,1,.857-.015,12.5,12.5,0,0,1-1.124,2.417,5.113,5.113,0,0,0-.6.8,1.106,1.106,0,0,1,.506.035,2.441,2.441,0,0,0-.943,1.424.512.512,0,0,1,.461-.03c.266.105.426.476.667.406,0,0-.527.075-.652.451a2.645,2.645,0,0,1-.878,1.379s.351-.05.667.406c.135.2.506.035.506.035a4.343,4.343,0,0,1-.6.8,4.929,4.929,0,0,0-.517.647.412.412,0,0,1,.446.366.963.963,0,0,1-.517.647.63.63,0,0,1,.577.276c.226.326.361.522.536.5a3.894,3.894,0,0,0-.471.712,4.628,4.628,0,0,1-.993,1.073.619.619,0,0,1,.226.326c.025.176.05.351.16.371s-.286,0-.547.185a3,3,0,0,0-.477.426,1.133,1.133,0,0,1,.511.321,2.252,2.252,0,0,0,1.329.527,1.213,1.213,0,0,0-.562.582,9.586,9.586,0,0,1-1.535,1.544s1.715,1.224,2.086,1.063a3.572,3.572,0,0,0-.823.762,8.241,8.241,0,0,1-1.234,1.143.694.694,0,0,1,.4.3.875.875,0,0,0,.511.321s-.085.155-.632.341a2.265,2.265,0,0,0-.913.632s.577.276.817.206.772.141.752.251a.507.507,0,0,0-.522.361,1.177,1.177,0,0,1,.642.231c.246.216,1.314.923,1.73.828a.738.738,0,0,1-.391.271c-.306.115-.166.6-.471.712a2.592,2.592,0,0,1,.953.4c.4.3.627.627,1,.467,0,0-.436.205-.5.536s-.281.291-.281.291a1.659,1.659,0,0,1,.8.6c.316.456,1.524.392,2.061.888s.646.517.822.492a3.363,3.363,0,0,1-1.434.993c-1.595.621-1.364,1.233-1.715,1.283a.344.344,0,0,1,.311.171.606.606,0,0,0,.356.236,2.4,2.4,0,0,0-.722.21,5.168,5.168,0,0,1-1.179.526.582.582,0,0,1,.205.436c.005.286.562.672.562.672a4.112,4.112,0,0,0-1.008.215c-.371.16-1.224.461-1.424.311a.412.412,0,0,1,.16.371.945.945,0,0,0,.14.481s-.18-.261-.356-.236a2.169,2.169,0,0,1-.506-.035,3.207,3.207,0,0,0,.346.918c.3.567-.015.4.256.787a6.451,6.451,0,0,0-1.143.02,3.007,3.007,0,0,1-1.715.03s.18.261.03.461a.932.932,0,0,0-.055.617,1.5,1.5,0,0,0-.572.01,1.613,1.613,0,0,1-.857.015,1.724,1.724,0,0,1,.3.853c-.015.4.286,1.249.506,1.289a2.993,2.993,0,0,0-.747.035c-.241.07-.862-.271-1.083-.311s-1.163.13-1.254,0c0,0-.236.356-.166.6a1.1,1.1,0,0,0-.642-.231,1.767,1.767,0,0,1-.707-.186.83.83,0,0,1-.186.707.591.591,0,0,0-.166.6s-.271-.391-.557-.386a1.622,1.622,0,0,1-.908-.336c-.09-.13-.08.441-.08.441a.707.707,0,0,0-.557-.386,6.055,6.055,0,0,1-.076,1.013,1.213,1.213,0,0,0,.175.943,3.54,3.54,0,0,1,.175,1.229,1.419,1.419,0,0,0-.6-.166c-.286,0-1.72-.256-1.72-.256a1.5,1.5,0,0,1-.531-.211s.2.15.03.461-.08.441-.08.441-.381-.411-.667-.406a.943.943,0,0,1-.757-.537s.185.547-.01.682-.211.531-.211.531a4,4,0,0,0-1-.752,4.847,4.847,0,0,1-.978-.577,2.332,2.332,0,0,1-.161.882c-.15.2-.075.727-.075.727a1.6,1.6,0,0,0-1.2-.617,1.174,1.174,0,0,1-1.043-.532l-.015.4s-.687-.3-.712-.471a1.737,1.737,0,0,0-.075.727c.01.572-.512.933-.507,1.218,0,0,.015-.4-.316-.456l-.331-.06h0a2.633,2.633,0,0,1-.221,1.213,4.168,4.168,0,0,0-.311,2.337.981.981,0,0,0-.973-.291c-.7.1-1.419-.657-1.419-.657s-.216.246-.125.376a1.484,1.484,0,0,1-.667-.406,1.935,1.935,0,0,0-.381-.411,2.487,2.487,0,0,1-.737.607.293.293,0,0,0-.105.266s-.16-.371-.381-.411a1.478,1.478,0,0,1-.9-1.018.908.908,0,0,1-.391.271.619.619,0,0,0-.326.226s.06-.331-.14-.481a.837.837,0,0,1-.271-.391,1.579,1.579,0,0,1-.863.983c-.436.205-.411.381-.411.381a1.791,1.791,0,0,0-.431-.762,3.867,3.867,0,0,1-.777-1.68s-.236.356-.567.3a.447.447,0,0,0-.391.271.63.63,0,0,0-.055-.637,2.433,2.433,0,0,1-.391-.983,1.381,1.381,0,0,0-.632.341,2.353,2.353,0,0,1-1.088.657l-.2.135h0a1.132,1.132,0,0,0-.12-.592,4.649,4.649,0,0,1-.3-1.82l-.527.075a.613.613,0,0,0-.241.07s.191-.421.1-.552a1.476,1.476,0,0,1,.091-1.123,1.632,1.632,0,0,1-.812.08.617.617,0,0,0-.526.075,1.411,1.411,0,0,0,.005-.968,1.862,1.862,0,0,1-.04-1.033,4.477,4.477,0,0,0-1.4.2c-.7.386-1.1.085-1.62.446a1.081,1.081,0,0,0-.075-.527,2.97,2.97,0,0,1,.2-1.389,3.8,3.8,0,0,0,.025-1.078,1.111,1.111,0,0,0-.637.055c-.2.135.159-.56.521-.826s.268-.844.736-1.072a1.853,1.853,0,0,1-.687-.087c-.405-.121-.54.149-.54.149a5.8,5.8,0,0,1,1.088-1.331,4.112,4.112,0,0,0,.85-.861,3.685,3.685,0,0,0-.722.21,2.741,2.741,0,0,1,.762-.9c.646-.576.576-.816.576-.816s-.312.2-.523.057a.8.8,0,0,0-.431-.135s1.35-2.1,2.521-2.407c.564-.15,2.378-.1,3.051-1.825.416-1.067.4-1.675,1.188-2.092Z" transform="translate(-462.274 -0.252)" fill="#5a9b84" /> 8413 <path id="Path_12" data-name="Path 12" d="M740.031,82.449l-.1-6.922.324-3.711-.044-.227-3.251-1.7a11.665,11.665,0,0,0-2.289-1.984,12.315,12.315,0,0,1-3.242-2.642c-.988-1.149-1.184-1.27-1.4-1.537a7.5,7.5,0,0,1-1.136-1.271c-.37-.628-.711-.424-1.475-1.389s-2.15-2.851-2.15-2.851,2.482,2.8,3.145,3.384,2.436,2.685,2.688,2.816,1.466,1.492,3.036,2.623,2.85,2.238,3.214,2.485,2.9,1.467,2.9,1.467-.711-8.715-.234-12.066-.049-2.6.287-4.184l-.142,6s.016,5.179.179,5.693S740.53,71,740.53,71s3.613-2.628,4.587-3.287,3.672-2.171,4.026-2.5,2.667-1.765,3.132-2.022,4.858-3.1,5.217-3.3-5.742,3.893-5.742,3.893l-4.292,2.809s-2.931,1.964-3.073,2.062l-3.611,2.515c-.1.068-.151.2.105.361s2.995,1.913,3.367,2.057,5.15,2.543,5.15,2.543-3.823-1.693-4.236-1.825a9.566,9.566,0,0,1-1.208-.514c-.226-.117-2.144-1.264-2.144-1.264a11.134,11.134,0,0,0-1.259-.752c-.021.063-.152,1.824-.179,2.389a11.431,11.431,0,0,0-.145,3.041A35.347,35.347,0,0,1,740.031,82.449Z" transform="translate(-475.674 -35.9)" fill="#77ac9a" /> 8414 <path id="Path_13" data-name="Path 13" d="M747.7,114.975a18.044,18.044,0,0,1-2.714,3.291,34.237,34.237,0,0,0-2.867,3.094q-1.369,1.616-2.663,3.293c-.431.558-.849,1.127-1.258,1.7a20.682,20.682,0,0,0-1.242,1.715,20.852,20.852,0,0,1,1.04-1.858c.412-.577.831-1.148,1.264-1.709q1.294-1.685,2.671-3.3a34.344,34.344,0,0,1,2.9-3.123,17.852,17.852,0,0,0,2.667-3.239l0,0a.124.124,0,0,1,.2.14Z" transform="translate(-483.341 -75.279)" fill="#77ac9a" /> 8415 <path id="Path_14" data-name="Path 14" d="M747.266,124.114l-3.516.681c-.574.109-1.2.21-1.774.26a5.872,5.872,0,0,0-.856.184,3.2,3.2,0,0,0-.85.243,2.777,2.777,0,0,1,.779-.48,6.16,6.16,0,0,1,.892-.192c.616-.055,1.167-.147,1.765-.258l3.511-.681a.124.124,0,0,1,.051.242Z" transform="translate(-485.512 -81.241)" fill="#77ac9a" /> 8416 <path id="Path_15" data-name="Path 15" d="M768.036,134.965a40.908,40.908,0,0,1,1.258,3.941,7.883,7.883,0,0,0,.783,1.874l1.047,1.779,1.047,1.779c.321.609.622,1.222.965,1.815s.7,1.179,1.068,1.755c.331.6.7,1.187.986,1.816-.357-.588-.791-1.122-1.194-1.682-.374-.579-.735-1.166-1.075-1.767s-.651-1.218-.971-1.825l-1.045-1.775-1.045-1.775a8.127,8.127,0,0,1-.8-1.918c-.451-1.305-.678-2.684-1.245-3.908l0-.006a.124.124,0,1,1,.224-.1Z" transform="translate(-503.567 -88.471)" fill="#77ac9a" /> 8417 <path id="Path_16" data-name="Path 16" d="M752.621,146.4a7.7,7.7,0,0,0,.582-1.46l.578-1.466,1.107-2.957c.2-.5.344-.971.606-1.493a7.074,7.074,0,0,0,.769-1.345,9.992,9.992,0,0,1,1.609-2.736.124.124,0,1,1,.2.147l0,0a9.732,9.732,0,0,0-1.578,2.684,7.329,7.329,0,0,1-.8,1.392c-.206.421-.39.955-.575,1.435l-1.108,2.959-.581,1.472A7.778,7.778,0,0,1,752.621,146.4Z" transform="translate(-493.612 -88.472)" fill="#77ac9a" /> 8418 <path id="Path_17" data-name="Path 17" d="M777.165,161.344a2.551,2.551,0,0,0-.627,1.1c-.137.412-.174.87-.313,1.317a3.3,3.3,0,0,0-.231,1.29c.006.221.022.444.045.667L776,166.4c-.078-.218-.139-.439-.2-.661-.023-.227-.04-.456-.046-.687a3.555,3.555,0,0,1,.241-1.364c.132-.417.168-.872.315-1.322a2.725,2.725,0,0,1,.716-1.223.123.123,0,1,1,.165.182h0Z" transform="translate(-508.779 -105.666)" fill="#77ac9a" /> 8419 <path id="Path_18" data-name="Path 18" d="M768.406,150.479a8.548,8.548,0,0,0-.87,1.982l-.66,2.109c-.223.7-.425,1.426-.627,2.128-.1.355-.184.711-.254,1.07a8.043,8.043,0,0,0-.256,1.077,6.163,6.163,0,0,1,.013-1.124c.071-.367.16-.729.258-1.088.207-.72.4-1.418.627-2.128l.665-2.125a8.476,8.476,0,0,1,.917-2.063.123.123,0,0,1,.2.136Z" transform="translate(-502.203 -98.55)" fill="#77ac9a" /> 8420 <path id="Path_19" data-name="Path 19" d="M795.156,116.774c.069-.076.018-.023.039,0a.539.539,0,0,0,.034.1,1.765,1.765,0,0,0,.123.216,4.715,4.715,0,0,0,.318.417l.7.811q.713.8,1.469,1.565a17.756,17.756,0,0,0,3.28,2.723l.01.007c.827.572,1.711,1.088,2.581,1.614l2.62,1.573c.87.532,1.739,1.063,2.58,1.652a6.221,6.221,0,0,1,1.136,1.037,4.446,4.446,0,0,0,1.21.906,4.515,4.515,0,0,1-1.307-.8c-.2-.157-.387-.352-.578-.5s-.4-.3-.6-.446c-.828-.58-1.7-1.112-2.565-1.642l-2.618-1.572c-.872-.528-1.75-1.039-2.6-1.626l.01.007a17.977,17.977,0,0,1-3.331-2.762q-.76-.768-1.478-1.575l-.706-.818a4.906,4.906,0,0,1-.334-.439,2,2,0,0,1-.142-.251.765.765,0,0,1-.051-.154c.006-.064-.06-.116.076-.257a.124.124,0,0,1,.128.212Z" transform="translate(-521.368 -76.438)" fill="#77ac9a" /> 8421 <path id="Path_20" data-name="Path 20" d="M820.818,118.753a9.418,9.418,0,0,1-1.607.231l-1.62.133-3.246.085c-1.082.019-2.165.036-3.247.031-.543,0-1.071.015-1.616.052-.547.021-1.084.021-1.632.01a41.652,41.652,0,0,1-6.424-1l-6.32-1.51a.124.124,0,1,1,.058-.241h0l6.3,1.506a41.5,41.5,0,0,0,6.385,1c.534.011,1.079.011,1.613-.01.534-.037,1.088-.054,1.627-.052,1.082,0,2.161-.012,3.243-.031l3.242-.085,1.622-.009A9.359,9.359,0,0,0,820.818,118.753Z" transform="translate(-521.415 -76.431)" fill="#77ac9a" /> 8422 <path id="Path_21" data-name="Path 21" d="M846.918,123.678a2.873,2.873,0,0,0,1.081.913,14.261,14.261,0,0,0,1.371.6c.467.185.934.368,1.408.52a6.6,6.6,0,0,0,.716.192,2.352,2.352,0,0,0,.725.166,2.06,2.06,0,0,1-.774.077,6.708,6.708,0,0,1-.742-.2c-.485-.155-.956-.339-1.425-.525a14.37,14.37,0,0,1-1.4-.609,3.028,3.028,0,0,1-1.187-1.027.123.123,0,0,1,.21-.128h0Z" transform="translate(-555.298 -81.061)" fill="#77ac9a" /> 8423 <path id="Path_22" data-name="Path 22" d="M833.111,123.882a8.446,8.446,0,0,0,1.982,1.438c.732.392,1.49.746,2.251,1.086s1.534.659,2.315.948c.391.143.784.281,1.182.395a3.5,3.5,0,0,0,1.2.311,3.245,3.245,0,0,1-1.266-.073c-.407-.117-.8-.256-1.2-.4-.788-.293-1.563-.615-2.33-.954s-1.526-.7-2.269-1.1a8.495,8.495,0,0,1-2.06-1.506.123.123,0,1,1,.18-.168Z" transform="translate(-546.251 -81.211)" fill="#77ac9a" /> 8424 <path id="Path_23" data-name="Path 23" d="M814.65,121.22a17.748,17.748,0,0,0,2.708,2.674,16.817,16.817,0,0,0,3.258,1.969,24.505,24.505,0,0,0,3.555,1.413,16.173,16.173,0,0,1,1.784.751,10.161,10.161,0,0,1,1.587,1.1,10.018,10.018,0,0,0-1.7-.882,15.949,15.949,0,0,0-1.756-.739,24.768,24.768,0,0,1-3.58-1.424,17.031,17.031,0,0,1-3.305-2,17.971,17.971,0,0,1-2.75-2.718.124.124,0,1,1,.193-.155h0Z" transform="translate(-534.147 -79.469)" fill="#77ac9a" /> 8425 <path id="Path_24" data-name="Path 24" d="M780.794,110.492a9.845,9.845,0,0,0,.614,2.9,21.422,21.422,0,0,0,1.2,2.75,18.733,18.733,0,0,0,1.554,2.563,21.386,21.386,0,0,0,1.962,2.27c1.394,1.444,2.877,2.809,4.385,4.135a8.32,8.32,0,0,0,1.2.89c.419.282.836.568,1.239.875a10.136,10.136,0,0,1,2.094,2.184,10.022,10.022,0,0,0-2.243-1.986q-.6-.449-1.228-.867l-.63-.422c-.215-.155-.4-.322-.592-.486-1.515-1.333-3-2.7-4.4-4.151a21.622,21.622,0,0,1-1.984-2.3,18.961,18.961,0,0,1-1.574-2.6,21.689,21.689,0,0,1-1.214-2.781,10,10,0,0,1-.627-2.989.123.123,0,1,1,.247-.005Z" transform="translate(-511.928 -72.376)" fill="#77ac9a" /> 8426 <path id="Path_25" data-name="Path 25" d="M789.294,89c1.863.606,3.684,1.306,5.569,1.787.942.244,1.891.464,2.849.617a21.037,21.037,0,0,0,2.9.212,36.5,36.5,0,0,0,5.832-.107c.967-.1,1.929-.253,2.887-.428.967-.128,1.927-.313,2.9-.427-.957.194-1.9.46-2.855.67-.962.176-1.931.327-2.906.431a36.666,36.666,0,0,1-5.869.109,21.269,21.269,0,0,1-2.933-.214c-.97-.155-1.925-.377-2.873-.622-1.9-.486-3.734-1.19-5.583-1.791a.124.124,0,1,1,.077-.235Z" transform="translate(-517.558 -58.368)" fill="#77ac9a" /> 8427 <path id="Path_26" data-name="Path 26" d="M807.147,74.509l4.306.233a36.575,36.575,0,0,0,4.3-.176,31.716,31.716,0,0,0,4.24-.712,14.45,14.45,0,0,1,2.137-.4,5.524,5.524,0,0,0,2.105-.351,5.623,5.623,0,0,1-2.079.6,14.136,14.136,0,0,0-2.1.4,31.943,31.943,0,0,1-4.274.718,36.767,36.767,0,0,1-4.328.177l-4.322-.234a.124.124,0,1,1,.013-.247Z" transform="translate(-529.284 -47.943)" fill="#77ac9a" /> 8428 <path id="Path_27" data-name="Path 27" d="M818.6,51.7l3.771-2.147c1.276-.683,2.463-1.517,3.684-2.294s2.4-1.606,3.606-2.407c1.224-.763,2.321-1.728,3.6-2.439a16.651,16.651,0,0,0-1.662,1.393c-.561.458-1.193.826-1.786,1.243-1.208.8-2.4,1.637-3.621,2.417s-2.41,1.612-3.69,2.3l-3.78,2.152a.124.124,0,1,1-.122-.215Z" transform="translate(-536.844 -27.818)" fill="#77ac9a" /> 8429 <path id="Path_28" data-name="Path 28" d="M838.226,57.368a5.528,5.528,0,0,0,1.648.443,7.512,7.512,0,0,0,1.725,0,8.617,8.617,0,0,0,1.689-.376c.274-.094.54-.2.832-.293a3.83,3.83,0,0,1,.9-.055,4.9,4.9,0,0,0-.824.291c-.267.085-.546.195-.827.291a8.873,8.873,0,0,1-1.738.387,7.763,7.763,0,0,1-1.784,0,5.726,5.726,0,0,1-1.733-.469.123.123,0,1,1,.1-.224h0Z" transform="translate(-549.635 -37.439)" fill="#77ac9a" /> 8430 <path id="Path_29" data-name="Path 29" d="M839.631,46.669a6.875,6.875,0,0,1,.962-2.538,5.145,5.145,0,0,1,.91-1.012,5.28,5.28,0,0,0,.443-.48,1.862,1.862,0,0,0,.177-.257.59.59,0,0,0,.052-.125c.023-.034-.022-.079.033-.023l-.021-.194a4.075,4.075,0,0,1,.5-.446c.183-.131.364-.265.552-.39-.133.183-.275.357-.414.535a4.106,4.106,0,0,1-.467.48l-.021-.194a.26.26,0,0,1,.078.292.83.83,0,0,1-.074.184,2.081,2.081,0,0,1-.2.294,5.544,5.544,0,0,1-.464.5,4.882,4.882,0,0,0-.876.972,6.646,6.646,0,0,0-.923,2.437v.008a.124.124,0,0,1-.243-.044Z" transform="translate(-550.677 -27.023)" fill="#77ac9a" /> 8431 <path id="Path_30" data-name="Path 30" d="M830.4,46.345a31.818,31.818,0,0,1,1.5-4.632,18.628,18.628,0,0,1,1.066-2.194,10.881,10.881,0,0,1,.663-1.03,7.674,7.674,0,0,1,.876-.858,10.205,10.205,0,0,0-.676,1,10.625,10.625,0,0,0-.649,1.008,18.386,18.386,0,0,0-1.052,2.166,31.572,31.572,0,0,0-1.484,4.591v0a.124.124,0,0,1-.24-.059Z" transform="translate(-544.619 -24.68)" fill="#77ac9a" /> 8432 <path id="Path_31" data-name="Path 31" d="M827.407,63.97a19.83,19.83,0,0,0,2.534.48,11.834,11.834,0,0,0,2.567.065c.863-.073,1.725-.146,2.58-.255.427-.056.854-.119,1.271-.21a2.971,2.971,0,0,0,1.224-.349,2.83,2.83,0,0,1-1.172.59c-.429.093-.861.157-1.292.214-.863.11-1.728.183-2.591.256a12.091,12.091,0,0,1-2.618-.065,20.068,20.068,0,0,1-2.569-.487.124.124,0,0,1,.062-.24Z" transform="translate(-542.558 -41.779)" fill="#77ac9a" /> 8433 <path id="Path_32" data-name="Path 32" d="M807.573,46.313a35.731,35.731,0,0,1,1.241-4.381,28.328,28.328,0,0,1,1.859-4.155c.709-1.339,1.449-2.664,2.291-3.931.827-1.338,2.126-2.167,3.027-3.387a12.233,12.233,0,0,1-1.364,1.819l-.788.819a7.593,7.593,0,0,0-.669.887c-.833,1.253-1.571,2.574-2.277,3.908a28.055,28.055,0,0,0-1.845,4.122,35.536,35.536,0,0,0-1.231,4.347v0a.124.124,0,1,1-.242-.052Z" transform="translate(-529.651 -19.977)" fill="#77ac9a" /> 8434 <path id="Path_33" data-name="Path 33" d="M788.989,45.215a21.088,21.088,0,0,0,.428-2.962,20.244,20.244,0,0,1,.277-3.011,40.473,40.473,0,0,1,1.318-5.9,48.144,48.144,0,0,1,2.329-5.577c.443-.9.9-1.8,1.428-2.668a11.827,11.827,0,0,0,1.552-2.57,11.92,11.92,0,0,1-1.341,2.7c-.52.85-.975,1.747-1.415,2.646a47.945,47.945,0,0,0-2.315,5.543,40.245,40.245,0,0,0-1.31,5.86,19.991,19.991,0,0,0-.275,2.987,21.331,21.331,0,0,1-.434,3,.124.124,0,1,1-.242-.05Z" transform="translate(-517.462 -14.775)" fill="#77ac9a" /> 8435 <path id="Path_34" data-name="Path 34" d="M768.072,19.083l.251-4.693c.1-1.565.136-3.126.158-4.692s.006-3.13-.07-4.691c-.037-.78-.093-1.56-.189-2.332A7.67,7.67,0,0,0,767.8.384a7.774,7.774,0,0,1,.665,2.261c.1.782.153,1.566.19,2.35.077,1.569.087,3.138.071,4.706s-.062,3.138-.159,4.7l-.251,4.693a.124.124,0,1,1-.247-.013Z" transform="translate(-503.569 -0.252)" fill="#77ac9a" /> 8436 <path id="Path_35" data-name="Path 35" d="M762.081,16.89l-2.428-2.932a11.105,11.105,0,0,1-1.02-1.627q-.222-.425-.413-.866a5.723,5.723,0,0,1-.211-.941,8.154,8.154,0,0,0,.438.843q.186.432.4.85a10.88,10.88,0,0,0,1,1.59l2.422,2.925a.124.124,0,0,1-.189.159Z" transform="translate(-497.146 -6.902)" fill="#77ac9a" /> 8437 <path id="Path_36" data-name="Path 36" d="M756.863,26.857a23.117,23.117,0,0,1-3.781-4.625,21.87,21.87,0,0,1-1.5-2.594l-.29-.685-.339-.659-.569-1.378.792,1.27.342.665.291.685a21.7,21.7,0,0,0,1.477,2.56,22.889,22.889,0,0,0,3.734,4.571l.006.005a.124.124,0,0,1-.167.182Z" transform="translate(-492.147 -11.095)" fill="#77ac9a" /> 8438 <path id="Path_37" data-name="Path 37" d="M751.605,40.819a34.287,34.287,0,0,1-2.431-3.3c-.749-1.139-1.454-2.309-2.091-3.516a37.587,37.587,0,0,1-1.711-3.709,13.49,13.49,0,0,0-.984-1.763,4.506,4.506,0,0,0-1.3-1.522,4.618,4.618,0,0,1,1.509,1.384,13.725,13.725,0,0,1,1,1.8,37.414,37.414,0,0,0,1.705,3.7c.632,1.2,1.333,2.362,2.079,3.5a34.118,34.118,0,0,0,2.409,3.268l0,0a.124.124,0,0,1-.189.16Z" transform="translate(-487.358 -17.716)" fill="#77ac9a" /> 8439 <path id="Path_38" data-name="Path 38" d="M747.181,47.516a40.23,40.23,0,0,1-4.232-4.383,26.8,26.8,0,0,1-1.775-2.481A24.032,24.032,0,0,1,739.666,38a34.742,34.742,0,0,1-2.03-5.744q-.4-1.469-.719-2.96l-.233-1.505a11.111,11.111,0,0,0-.258-1.494,11.106,11.106,0,0,1,.38,1.471l.353,1.476q.315,1.483.715,2.945a34.5,34.5,0,0,0,2.014,5.7,23.794,23.794,0,0,0,1.494,2.626,26.555,26.555,0,0,0,1.759,2.459,40.016,40.016,0,0,0,4.2,4.353.124.124,0,0,1-.161.188Z" transform="translate(-482.991 -17.246)" fill="#77ac9a" /> 8440 <path id="Path_39" data-name="Path 39" d="M714.161,63.262c-.49-.057-.983-.107-1.474-.147a12.509,12.509,0,0,0-1.47-.057,6.532,6.532,0,0,1-1.5-.17,6.727,6.727,0,0,1-.729-.2,2.624,2.624,0,0,1-.629-.434,3.255,3.255,0,0,0,.71.2,6.517,6.517,0,0,0,.7.2,6.329,6.329,0,0,0,1.442.164,12.713,12.713,0,0,1,1.5.058c.5.041.989.091,1.483.148a.124.124,0,0,1-.028.246Z" transform="translate(-464.579 -40.827)" fill="#77ac9a" /> 8441 <path id="Path_40" data-name="Path 40" d="M713.224,48.234c.248.169.484.352.721.537.207.214.411.433.6.663a9.537,9.537,0,0,1,1.024,1.476c.3.516.541,1.064.834,1.567a5.569,5.569,0,0,0,1.037,1.37l.015.013a.123.123,0,0,1-.163.185h0a5.683,5.683,0,0,1-1.1-1.445c-.3-.521-.537-1.063-.834-1.568a9.271,9.271,0,0,0-1-1.439c-.187-.224-.387-.439-.592-.65Z" transform="translate(-467.773 -31.635)" fill="#77ac9a" /> 8442 <path id="Path_41" data-name="Path 41" d="M713.849,70.752q-1.143.073-2.285.1a20.681,20.681,0,0,1-2.3-.044,14.12,14.12,0,0,1-2.249-.486l-1.1-.316a3.713,3.713,0,0,0-1.082-.319,3.314,3.314,0,0,1,1.149.081l1.1.316a13.887,13.887,0,0,0,2.207.478,20.513,20.513,0,0,0,2.265.042c.758-.019,1.518-.053,2.275-.1a.124.124,0,1,1,.018.247Z" transform="translate(-462.275 -45.694)" fill="#77ac9a" /> 8443 <path id="Path_42" data-name="Path 42" d="M719.966,85.662c-.81.115-1.62.207-2.435.273a19.611,19.611,0,0,1-2.456.07c-1.636-.1-3.249-.331-4.862-.573l-.013,0c-.571-.148-1.144-.295-1.72-.421l-.853-.241a3.385,3.385,0,0,0-.867-.156,3.43,3.43,0,0,1,.892.026c.3.036.593.068.884.125.578.136,1.154.276,1.728.428l-.012,0c1.605.242,3.222.47,4.836.571a19.5,19.5,0,0,0,2.423-.07c.808-.066,1.617-.157,2.418-.271a.124.124,0,1,1,.038.244Z" transform="translate(-463.534 -55.481)" fill="#77ac9a" /> 8444 <path id="Path_43" data-name="Path 43" d="M728.321,98.625a33.363,33.363,0,0,1-3.9,1.458,15.066,15.066,0,0,1-2.036.471,20.748,20.748,0,0,1-2.083.124,23.842,23.842,0,0,1-4.162-.108,19.116,19.116,0,0,0-2.055-.146q-1.031-.085-2.071-.111,1.034-.1,2.077-.136a19.419,19.419,0,0,1,2.082.148,23.576,23.576,0,0,0,4.121.107c.69-.033,1.387-.021,2.056-.121a14.831,14.831,0,0,0,2-.463,33.18,33.18,0,0,0,3.867-1.446.124.124,0,1,1,.105.224Z" transform="translate(-466.981 -64.526)" fill="#77ac9a" /> 8445 <path id="Path_44" data-name="Path 44" d="M729.448,104.4a21.76,21.76,0,0,1-2.524,2.284,10.7,10.7,0,0,1-1.43.94,6.145,6.145,0,0,1-.786.36l-.432.069c-.147,0-.293,0-.433,0l.4-.124.378-.176a5.94,5.94,0,0,0,.752-.345,10.484,10.484,0,0,0,1.4-.918,21.543,21.543,0,0,0,2.492-2.256l0,0a.124.124,0,0,1,.179.17Z" transform="translate(-474.738 -68.339)" fill="#77ac9a" /> 8446 <path id="Path_45" data-name="Path 45" d="M740.509,101.543c-.876,1.037-1.795,2.033-2.768,2.978q-.728.711-1.525,1.353c-.265.215-.545.411-.829.6a4.978,4.978,0,0,1-.965.362l.431-.267.4-.3c.276-.187.549-.378.809-.59q.784-.629,1.507-1.337c.965-.937,1.882-1.932,2.75-2.959a.124.124,0,1,1,.192.156Z" transform="translate(-481.676 -66.461)" fill="#77ac9a" /> 8447 <path id="Path_46" data-name="Path 46" d="M740.031,82.45l-.1-6.922.324-3.711-.044-.226-3.251-1.7a11.665,11.665,0,0,0-2.289-1.984,12.313,12.313,0,0,1-3.242-2.642c-.988-1.149-1.184-1.27-1.4-1.537a7.5,7.5,0,0,1-1.136-1.271c-.37-.628-.711-.424-1.476-1.389s-2.15-2.851-2.15-2.851,2.482,2.8,3.145,3.384,2.436,2.685,2.688,2.816,1.466,1.492,3.036,2.623,2.85,2.238,3.214,2.485,2.9,1.467,2.9,1.467-.712-8.715-.234-12.066-.049-2.6.287-4.184l-.142,6s.016,5.179.179,5.693S740.53,71,740.53,71s3.613-2.628,4.587-3.287,3.672-2.171,4.026-2.5,2.667-1.765,3.132-2.022,4.858-3.1,5.217-3.3-5.742,3.893-5.742,3.893l-4.292,2.809s-2.931,1.964-3.073,2.062l-3.611,2.515c-.1.068-.151.2.105.361s2.995,1.913,3.367,2.057,5.15,2.543,5.15,2.543-3.823-1.693-4.236-1.826a9.563,9.563,0,0,1-1.208-.514c-.226-.117-2.144-1.264-2.144-1.264a11.115,11.115,0,0,0-1.259-.752c-.021.063-.152,1.824-.179,2.389a11.429,11.429,0,0,0-.145,3.041A35.352,35.352,0,0,1,740.031,82.45Z" transform="translate(-475.673 -35.9)" fill="#77ac9a" /> 8448 <path id="Path_47" data-name="Path 47" d="M747.7,114.977a18.041,18.041,0,0,1-2.714,3.292,34.25,34.25,0,0,0-2.867,3.094q-1.369,1.616-2.663,3.293c-.431.559-.849,1.127-1.258,1.7a20.788,20.788,0,0,0-1.242,1.715,20.947,20.947,0,0,1,1.04-1.858c.412-.577.831-1.148,1.264-1.709q1.294-1.685,2.671-3.3a34.323,34.323,0,0,1,2.9-3.123,17.845,17.845,0,0,0,2.667-3.239l0,0a.124.124,0,0,1,.2.14Z" transform="translate(-483.341 -75.281)" fill="#77ac9a" /> 8449 <path id="Path_48" data-name="Path 48" d="M747.266,124.115l-3.516.681c-.574.108-1.2.21-1.774.26a5.916,5.916,0,0,0-.856.184,3.207,3.207,0,0,0-.85.243,2.777,2.777,0,0,1,.779-.48,6.161,6.161,0,0,1,.892-.192c.616-.055,1.167-.147,1.765-.258l3.511-.681a.124.124,0,0,1,.051.242Z" transform="translate(-485.512 -81.241)" fill="#77ac9a" /> 8450 <path id="Path_49" data-name="Path 49" d="M768.036,134.967a40.907,40.907,0,0,1,1.258,3.941,7.881,7.881,0,0,0,.784,1.874l1.047,1.779,1.047,1.779c.321.609.622,1.222.965,1.815s.7,1.179,1.068,1.755c.331.6.7,1.188.986,1.816-.357-.588-.791-1.122-1.194-1.682-.374-.579-.735-1.167-1.075-1.767s-.651-1.219-.97-1.825l-1.045-1.775-1.045-1.775a8.134,8.134,0,0,1-.8-1.918c-.451-1.305-.678-2.684-1.245-3.908l0-.006a.124.124,0,1,1,.224-.1Z" transform="translate(-503.568 -88.472)" fill="#77ac9a" /> 8451 <path id="Path_50" data-name="Path 50" d="M752.621,137.407c.518-.915.734-1.966,1.16-2.926l1.107-2.957c.2-.5.344-.971.606-1.493a7.083,7.083,0,0,0,.769-1.345,9.994,9.994,0,0,1,1.609-2.736l-.026.072.111-4.724a.124.124,0,0,1,.247.006l-.111,4.724a.133.133,0,0,1-.026.073,9.743,9.743,0,0,0-1.578,2.684,7.328,7.328,0,0,1-.8,1.391c-.206.421-.39.955-.575,1.435l-1.108,2.959a14.218,14.218,0,0,1-.612,1.459A7.768,7.768,0,0,1,752.621,137.407Z" transform="translate(-493.612 -79.474)" fill="#77ac9a" /> 8452 <path id="Path_51" data-name="Path 51" d="M777.165,161.35a2.552,2.552,0,0,0-.627,1.1c-.137.412-.174.869-.313,1.317a3.3,3.3,0,0,0-.231,1.29c.006.221.022.444.045.667l-.043.686c-.078-.218-.139-.439-.2-.662-.023-.227-.04-.456-.046-.687a3.559,3.559,0,0,1,.241-1.365c.132-.417.168-.872.315-1.321a2.727,2.727,0,0,1,.716-1.223.123.123,0,1,1,.165.183h0Z" transform="translate(-508.779 -105.671)" fill="#77ac9a" /> 8453 <path id="Path_52" data-name="Path 52" d="M768.406,150.481a8.536,8.536,0,0,0-.87,1.982l-.66,2.109c-.223.7-.425,1.427-.627,2.128-.1.354-.184.711-.254,1.07a8.086,8.086,0,0,0-.256,1.076,6.176,6.176,0,0,1,.013-1.123c.071-.367.161-.729.258-1.088.207-.72.4-1.418.627-2.128l.665-2.125a8.475,8.475,0,0,1,.917-2.063.123.123,0,1,1,.2.136Z" transform="translate(-502.203 -98.551)" fill="#77ac9a" /> 8454 <path id="Path_53" data-name="Path 53" d="M795.156,116.77c.069-.076.018-.023.039,0a.535.535,0,0,0,.034.1,1.761,1.761,0,0,0,.123.216,4.671,4.671,0,0,0,.318.417l.7.811q.713.8,1.469,1.565a17.757,17.757,0,0,0,3.28,2.723l.01.007c.827.572,1.711,1.088,2.581,1.614l2.62,1.573c.87.532,1.739,1.063,2.58,1.652a6.22,6.22,0,0,1,1.136,1.037,4.452,4.452,0,0,0,1.21.906,4.517,4.517,0,0,1-1.307-.8c-.2-.157-.387-.352-.578-.5s-.4-.3-.6-.446c-.828-.58-1.7-1.112-2.565-1.642l-2.618-1.572c-.872-.528-1.75-1.039-2.6-1.626l.01.007a17.965,17.965,0,0,1-3.331-2.763q-.761-.767-1.478-1.575l-.706-.818a4.971,4.971,0,0,1-.334-.439,1.99,1.99,0,0,1-.142-.252.765.765,0,0,1-.051-.154c.006-.064-.06-.116.076-.257a.124.124,0,1,1,.128.212Z" transform="translate(-521.369 -76.434)" fill="#77ac9a" /> 8455 <path id="Path_54" data-name="Path 54" d="M820.82,118.755a9.422,9.422,0,0,1-1.607.231l-1.62.133-3.246.085c-1.082.019-2.165.036-3.247.031-.543,0-1.07.015-1.616.052-.547.021-1.084.021-1.632.01a41.616,41.616,0,0,1-6.424-1l-6.32-1.51a.124.124,0,1,1,.057-.241h0l6.3,1.507a41.5,41.5,0,0,0,6.385,1c.534.011,1.079.011,1.613-.01.534-.036,1.088-.054,1.627-.052,1.082,0,2.161-.011,3.243-.031l3.242-.085,1.622-.009A9.393,9.393,0,0,0,820.82,118.755Z" transform="translate(-521.416 -76.432)" fill="#77ac9a" /> 8456 <path id="Path_55" data-name="Path 55" d="M846.918,123.68a2.87,2.87,0,0,0,1.081.913,14.174,14.174,0,0,0,1.371.6c.466.185.934.368,1.408.52a6.609,6.609,0,0,0,.716.192,2.351,2.351,0,0,0,.725.166,2.061,2.061,0,0,1-.774.077,6.789,6.789,0,0,1-.742-.2c-.485-.155-.956-.339-1.425-.526a14.3,14.3,0,0,1-1.4-.608,3.027,3.027,0,0,1-1.187-1.027.123.123,0,0,1,.21-.128h0Z" transform="translate(-555.299 -81.062)" fill="#77ac9a" /> 8457 <path id="Path_56" data-name="Path 56" d="M833.112,123.884a8.435,8.435,0,0,0,1.982,1.438c.732.392,1.49.747,2.251,1.086s1.534.659,2.315.949c.391.143.784.281,1.182.395a3.5,3.5,0,0,0,1.2.311,3.246,3.246,0,0,1-1.266-.073c-.407-.117-.8-.256-1.2-.4-.788-.293-1.563-.615-2.33-.954s-1.526-.7-2.269-1.1a8.5,8.5,0,0,1-2.06-1.506.123.123,0,0,1,.18-.168h0Z" transform="translate(-546.252 -81.212)" fill="#77ac9a" /> 8458 <path id="Path_57" data-name="Path 57" d="M814.651,121.222a17.751,17.751,0,0,0,2.707,2.674,16.816,16.816,0,0,0,3.258,1.969,24.512,24.512,0,0,0,3.555,1.413,16.174,16.174,0,0,1,1.784.751,10.165,10.165,0,0,1,1.587,1.1,10.015,10.015,0,0,0-1.7-.882,15.946,15.946,0,0,0-1.756-.739,24.773,24.773,0,0,1-3.581-1.424,17.046,17.046,0,0,1-3.306-2,17.952,17.952,0,0,1-2.75-2.718.124.124,0,0,1,.193-.154Z" transform="translate(-534.147 -79.47)" fill="#77ac9a" /> 8459 <path id="Path_58" data-name="Path 58" d="M780.794,110.493a9.841,9.841,0,0,0,.614,2.9,21.443,21.443,0,0,0,1.2,2.75,18.726,18.726,0,0,0,1.554,2.563,21.383,21.383,0,0,0,1.962,2.27c1.394,1.444,2.877,2.809,4.385,4.135a8.285,8.285,0,0,0,1.2.89c.419.282.836.568,1.239.875a10.143,10.143,0,0,1,2.094,2.184,10.024,10.024,0,0,0-2.243-1.986q-.6-.449-1.228-.867l-.63-.422c-.215-.155-.4-.322-.592-.486-1.515-1.333-3-2.7-4.4-4.151a21.622,21.622,0,0,1-1.984-2.3,18.966,18.966,0,0,1-1.574-2.6,21.7,21.7,0,0,1-1.214-2.782,9.995,9.995,0,0,1-.627-2.989.123.123,0,0,1,.247-.006Z" transform="translate(-511.927 -72.377)" fill="#77ac9a" /> 8460 <path id="Path_59" data-name="Path 59" d="M789.3,89.006c1.863.606,3.684,1.306,5.569,1.787.942.244,1.891.464,2.85.617a20.984,20.984,0,0,0,2.9.212,36.426,36.426,0,0,0,5.833-.107c.967-.1,1.929-.253,2.887-.428.967-.128,1.927-.313,2.9-.427-.957.195-1.9.46-2.855.67-.963.176-1.931.328-2.906.431a36.75,36.75,0,0,1-5.869.109,21.322,21.322,0,0,1-2.933-.215c-.97-.155-1.926-.377-2.874-.622-1.9-.486-3.734-1.19-5.583-1.791a.124.124,0,0,1,.077-.235Z" transform="translate(-517.567 -58.372)" fill="#77ac9a" /> 8461 <path id="Path_60" data-name="Path 60" d="M807.147,74.51l4.306.233a36.5,36.5,0,0,0,4.3-.176,31.661,31.661,0,0,0,4.24-.712,14.453,14.453,0,0,1,2.137-.4,5.518,5.518,0,0,0,2.105-.351,5.624,5.624,0,0,1-2.079.6,14.138,14.138,0,0,0-2.1.4,31.941,31.941,0,0,1-4.274.718,36.762,36.762,0,0,1-4.328.177l-4.322-.234a.124.124,0,0,1,.013-.247h0Z" transform="translate(-529.284 -47.943)" fill="#77ac9a" /> 8462 <path id="Path_61" data-name="Path 61" d="M824.467,42.285a16.6,16.6,0,0,0-1.724,1.286c-.561.457-1.193.825-1.786,1.243-1.208.8-2.4,1.637-3.621,2.417s-2.41,1.612-3.69,2.3l-3.78,2.152.008,0-2.387,1.557-2.453,1.456,2.319-1.661,2.386-1.559.008,0,3.771-2.147c1.276-.683,2.463-1.517,3.684-2.294s2.4-1.606,3.606-2.407c.591-.415,1.217-.779,1.779-1.237a16.671,16.671,0,0,1,1.756-1.309.124.124,0,0,1,.129.211h0Z" transform="translate(-527.987 -27.58)" fill="#77ac9a" /> 8463 <path id="Path_62" data-name="Path 62" d="M838.227,57.369a5.528,5.528,0,0,0,1.648.443,7.511,7.511,0,0,0,1.725,0,8.645,8.645,0,0,0,1.689-.376c.274-.094.54-.2.832-.293a3.812,3.812,0,0,1,.9-.055,4.907,4.907,0,0,0-.825.291c-.267.085-.546.2-.827.292a8.9,8.9,0,0,1-1.738.387,7.783,7.783,0,0,1-1.784,0,5.727,5.727,0,0,1-1.733-.469.123.123,0,0,1,.1-.224h0Z" transform="translate(-549.635 -37.439)" fill="#77ac9a" /> 8464 <path id="Path_63" data-name="Path 63" d="M839.632,46.669a6.88,6.88,0,0,1,.962-2.538,5.137,5.137,0,0,1,.91-1.012,5.3,5.3,0,0,0,.443-.48,1.854,1.854,0,0,0,.177-.257.586.586,0,0,0,.052-.125c.023-.034-.022-.079.033-.023l-.021-.195a4.07,4.07,0,0,1,.5-.446c.183-.131.364-.265.552-.391-.134.183-.275.358-.414.535a4.079,4.079,0,0,1-.467.48l-.021-.195a.261.261,0,0,1,.078.292.824.824,0,0,1-.074.184,2.1,2.1,0,0,1-.2.294,5.571,5.571,0,0,1-.464.5,4.882,4.882,0,0,0-.876.972,6.641,6.641,0,0,0-.923,2.437v.008a.124.124,0,0,1-.243-.043Z" transform="translate(-550.678 -27.023)" fill="#77ac9a" /> 8465 <path id="Path_64" data-name="Path 64" d="M830.4,46.346a31.811,31.811,0,0,1,1.5-4.632,18.668,18.668,0,0,1,1.066-2.195,10.886,10.886,0,0,1,.663-1.03,7.649,7.649,0,0,1,.876-.858,10.161,10.161,0,0,0-.676,1,10.655,10.655,0,0,0-.649,1.008,18.375,18.375,0,0,0-1.052,2.166,31.577,31.577,0,0,0-1.484,4.592v0a.124.124,0,1,1-.24-.059Z" transform="translate(-544.62 -24.681)" fill="#77ac9a" /> 8466 <path id="Path_65" data-name="Path 65" d="M827.409,63.971a19.83,19.83,0,0,0,2.534.48,11.833,11.833,0,0,0,2.567.065c.863-.073,1.725-.146,2.58-.255.427-.056.853-.119,1.271-.21a2.965,2.965,0,0,0,1.224-.348,2.83,2.83,0,0,1-1.171.59c-.429.093-.861.157-1.292.214-.863.11-1.728.183-2.591.256a12.091,12.091,0,0,1-2.618-.065,20.07,20.07,0,0,1-2.569-.487.124.124,0,0,1,.062-.24Z" transform="translate(-542.558 -41.78)" fill="#77ac9a" /> 8467 <path id="Path_66" data-name="Path 66" d="M807.574,46.314a35.742,35.742,0,0,1,1.241-4.381,28.334,28.334,0,0,1,1.859-4.155c.709-1.339,1.449-2.664,2.291-3.931.827-1.338,2.125-2.167,3.027-3.387a12.228,12.228,0,0,1-1.364,1.818l-.788.82a7.609,7.609,0,0,0-.669.887c-.833,1.253-1.571,2.575-2.277,3.908a28.06,28.06,0,0,0-1.845,4.122,35.518,35.518,0,0,0-1.231,4.347v0a.124.124,0,0,1-.242-.052Z" transform="translate(-529.652 -19.977)" fill="#77ac9a" /> 8468 <path id="Path_67" data-name="Path 67" d="M788.989,45.215a21.088,21.088,0,0,0,.428-2.962,20.244,20.244,0,0,1,.277-3.011,40.489,40.489,0,0,1,1.319-5.9,48.143,48.143,0,0,1,2.329-5.577c.443-.9.9-1.8,1.428-2.669a11.816,11.816,0,0,0,1.551-2.571,11.917,11.917,0,0,1-1.341,2.7c-.52.85-.975,1.747-1.415,2.646a47.9,47.9,0,0,0-2.315,5.544,40.237,40.237,0,0,0-1.31,5.86,20.007,20.007,0,0,0-.275,2.987,21.322,21.322,0,0,1-.434,3,.124.124,0,1,1-.242-.05Z" transform="translate(-517.462 -14.775)" fill="#77ac9a" /> 8469 <path id="Path_68" data-name="Path 68" d="M767.67.074a10.27,10.27,0,0,1,.639,3.072c.092,1.034.135,2.07.164,3.106.044,2.072.016,4.142-.06,6.212l-.326,6.2-.149,3.094-.271,3.1.024-3.1.149-3.1.325-6.195c.076-2.064.1-4.132.06-6.2-.029-1.032-.072-2.063-.163-3.09a10.175,10.175,0,0,0-.611-2.977l-.008-.017a.123.123,0,1,1,.226-.1Z" transform="translate(-503.327 0)" fill="#77ac9a" /> 8470 <path id="Path_69" data-name="Path 69" d="M762.08,16.89l-2.428-2.932a11.126,11.126,0,0,1-1.02-1.627q-.223-.425-.413-.866a5.723,5.723,0,0,1-.211-.941,8.143,8.143,0,0,0,.438.843q.186.432.4.85a10.881,10.881,0,0,0,1,1.59l2.422,2.925a.124.124,0,1,1-.189.159Z" transform="translate(-497.146 -6.902)" fill="#77ac9a" /> 8471 <path id="Path_70" data-name="Path 70" d="M756.863,26.857a23.107,23.107,0,0,1-3.781-4.624,21.869,21.869,0,0,1-1.5-2.594l-.29-.685-.339-.659-.569-1.378.792,1.27.342.665.291.685a21.667,21.667,0,0,0,1.477,2.56,22.892,22.892,0,0,0,3.734,4.571l.006.005a.124.124,0,0,1-.167.182Z" transform="translate(-492.147 -11.095)" fill="#77ac9a" /> 8472 <path id="Path_71" data-name="Path 71" d="M751.605,40.82a34.285,34.285,0,0,1-2.431-3.3c-.749-1.139-1.455-2.309-2.091-3.516a37.572,37.572,0,0,1-1.711-3.709,13.461,13.461,0,0,0-.984-1.763,4.5,4.5,0,0,0-1.3-1.522,4.616,4.616,0,0,1,1.509,1.384,13.709,13.709,0,0,1,1,1.8,37.45,37.45,0,0,0,1.705,3.7c.632,1.2,1.333,2.362,2.079,3.5a34.1,34.1,0,0,0,2.409,3.268l0,0a.124.124,0,1,1-.188.16Z" transform="translate(-487.358 -17.717)" fill="#77ac9a" /> 8473 <path id="Path_72" data-name="Path 72" d="M747.181,47.517a40.23,40.23,0,0,1-4.232-4.383,26.764,26.764,0,0,1-1.775-2.481A24.045,24.045,0,0,1,739.666,38a34.747,34.747,0,0,1-2.03-5.744q-.4-1.469-.719-2.96l-.233-1.505a11.117,11.117,0,0,0-.258-1.494,11.116,11.116,0,0,1,.38,1.471l.353,1.477q.315,1.482.715,2.945a34.493,34.493,0,0,0,2.014,5.7,23.8,23.8,0,0,0,1.494,2.626,26.545,26.545,0,0,0,1.759,2.459,40.019,40.019,0,0,0,4.2,4.353.124.124,0,1,1-.161.188Z" transform="translate(-482.99 -17.247)" fill="#77ac9a" /> 8474 <path id="Path_73" data-name="Path 73" d="M714.16,63.262c-.49-.057-.983-.107-1.474-.147a12.5,12.5,0,0,0-1.47-.057,6.529,6.529,0,0,1-1.5-.17,6.729,6.729,0,0,1-.729-.2,2.624,2.624,0,0,1-.629-.434,3.257,3.257,0,0,0,.71.2,6.523,6.523,0,0,0,.7.2,6.33,6.33,0,0,0,1.442.164,12.643,12.643,0,0,1,1.5.058c.5.041.989.091,1.483.148a.124.124,0,1,1-.028.246Z" transform="translate(-464.579 -40.827)" fill="#77ac9a" /> 8475 <path id="Path_74" data-name="Path 74" d="M713.223,48.235a6.439,6.439,0,0,1,1.324,1.2,9.522,9.522,0,0,1,1.024,1.476c.3.516.541,1.064.834,1.567a5.568,5.568,0,0,0,1.037,1.37l.013.011.006.007,1.059,1.2a.124.124,0,0,1-.186.164l-1.059-1.2.019.017a5.69,5.69,0,0,1-1.1-1.445c-.3-.521-.537-1.063-.834-1.568a9.285,9.285,0,0,0-1-1.439C713.964,49.164,713.6,48.7,713.223,48.235Z" transform="translate(-467.773 -31.635)" fill="#77ac9a" /> 8476 <path id="Path_75" data-name="Path 75" d="M713.849,70.753q-1.143.073-2.285.1a20.684,20.684,0,0,1-2.3-.044,14.117,14.117,0,0,1-2.249-.486l-1.1-.315a3.7,3.7,0,0,0-1.082-.32,3.314,3.314,0,0,1,1.149.081l1.1.316a13.892,13.892,0,0,0,2.207.478,20.442,20.442,0,0,0,2.265.042c.758-.019,1.518-.053,2.275-.1a.124.124,0,0,1,.018.247Z" transform="translate(-462.275 -45.695)" fill="#77ac9a" /> 8477 <path id="Path_76" data-name="Path 76" d="M719.966,85.663c-.81.115-1.62.207-2.435.273a19.676,19.676,0,0,1-2.456.07c-1.636-.1-3.249-.331-4.862-.574l-.013,0c-.571-.149-1.144-.3-1.72-.422l-.853-.241a3.385,3.385,0,0,0-.867-.156,3.431,3.431,0,0,1,.892.026c.3.036.593.068.885.125.578.136,1.154.276,1.728.428l-.012,0c1.605.242,3.222.47,4.836.571a19.43,19.43,0,0,0,2.423-.07c.808-.066,1.617-.157,2.418-.271a.124.124,0,0,1,.038.245Z" transform="translate(-463.534 -55.482)" fill="#77ac9a" /> 8478 <path id="Path_77" data-name="Path 77" d="M728.319,98.637a33.364,33.364,0,0,1-3.9,1.457,15.017,15.017,0,0,1-2.036.471,20.853,20.853,0,0,1-2.083.124,23.843,23.843,0,0,1-4.162-.109,19.2,19.2,0,0,0-2.055-.146q-1.031-.084-2.071-.112,1.035-.1,2.077-.136a19.418,19.418,0,0,1,2.081.148,23.611,23.611,0,0,0,4.121.106,20.549,20.549,0,0,0,2.056-.121,14.777,14.777,0,0,0,2-.463,33.121,33.121,0,0,0,3.867-1.445.124.124,0,0,1,.105.224Z" transform="translate(-466.979 -64.537)" fill="#77ac9a" /> 8479 <path id="Path_78" data-name="Path 78" d="M729.448,104.409a21.793,21.793,0,0,1-2.524,2.284,10.694,10.694,0,0,1-1.43.94,6.19,6.19,0,0,1-.786.36l-.432.069c-.147,0-.292,0-.433,0l.4-.125.378-.176a5.886,5.886,0,0,0,.752-.345,10.449,10.449,0,0,0,1.4-.918,21.539,21.539,0,0,0,2.492-2.255l0,0a.124.124,0,0,1,.179.171Z" transform="translate(-474.738 -68.343)" fill="#77ac9a" /> 8480 <path id="Path_79" data-name="Path 79" d="M740.508,101.562c-.876,1.037-1.795,2.033-2.768,2.979q-.728.711-1.525,1.353c-.265.215-.545.411-.829.6a4.962,4.962,0,0,1-.965.363l.431-.267.4-.3c.276-.187.549-.378.809-.59q.784-.629,1.507-1.336c.965-.938,1.882-1.932,2.75-2.959a.124.124,0,0,1,.192.156Z" transform="translate(-481.675 -66.48)" fill="#77ac9a" /> 8481 <path id="Path_80" data-name="Path 80" d="M754.387,99.154l1.986-.847.072.25Z" transform="translate(-494.77 -64.475)" fill="#77ac9a" /> 8482 <path id="Path_81" data-name="Path 81" d="M754.22,99.073a.088.088,0,0,1-.034-.17l1.985-.847a.091.091,0,0,1,.072,0,.088.088,0,0,1,.047.056l.072.249a.089.089,0,0,1-.06.11l-2.058.6A.1.1,0,0,1,754.22,99.073Zm1.928-.815-.549.234.569-.165Z" transform="translate(-494.603 -64.306)" fill="#77ac9a" /> 8483 <path id="Path_82" data-name="Path 82" d="M763.679,118.041a9.777,9.777,0,0,0,.79-1.4c.017-.208.133.2.133.2Z" transform="translate(-500.865 -76.46)" fill="#77ac9a" /> 8484 <path id="Path_83" data-name="Path 83" d="M763.51,117.959a.093.093,0,0,1-.051-.016.089.089,0,0,1-.023-.121,8.587,8.587,0,0,0,.776-1.359c.007-.087.04-.134.1-.14.074-.012.127.041.206.322a.089.089,0,0,1-.015.078l-.922,1.2A.087.087,0,0,1,763.51,117.959Zm.822-1.316-.012.028.015-.019Z" transform="translate(-500.696 -76.29)" fill="#77ac9a" /> 8485 <path id="Path_84" data-name="Path 84" d="M789.9,77.482s-.019,3.167-.13,3.447a.516.516,0,0,0,.066.5s2.154.987,2.782,1.2-3.123-1.055-3.123-1.055Z" transform="translate(-517.794 -50.817)" fill="#77ac9a" /> 8486 <path id="Path_85" data-name="Path 85" d="M792.527,82.565a.172.172,0,0,1-.04-.006h0l-.03-.01-.039-.013-.062-.021-3.062-1.033a.088.088,0,0,1-.06-.092l.406-4.086a.09.09,0,0,1,.092-.079.089.089,0,0,1,.084.089c0,.326-.022,3.191-.137,3.479a.427.427,0,0,0,.042.394c.225.1,2.169.988,2.752,1.184l.069.023-.007.021c.081.041.075.061.064.092A.073.073,0,0,1,792.527,82.565Zm-3.11-1.227.827.279c-.34-.153-.588-.266-.617-.28a.089.089,0,0,1-.031-.024.6.6,0,0,1-.08-.586,8.5,8.5,0,0,0,.086-1.242Z" transform="translate(-517.625 -50.649)" fill="#77ac9a" /> 8487 <path id="Path_86" data-name="Path 86" d="M790.813,114.132l-.019,0a41.193,41.193,0,0,1-7.236-2.672.088.088,0,0,1-.041-.118.086.086,0,0,1,.118-.041,41.032,41.032,0,0,0,7.2,2.659.088.088,0,0,1-.019.175Z" transform="translate(-513.87 -72.99)" fill="#77ac9a" /> 8488 <path id="Path_87" data-name="Path 87" d="M528.231,44.722c-.974-2.5-2.117-3.007-4.363-3.261v-.339h13v.339c-1.99.211-2.838.677-2.838,1.9a8.983,8.983,0,0,0,.8,3.305l5.846,14.741,4.447-11.734-2.244-5.719c-.721-1.948-2.034-2.33-3.727-2.5v-.339h12.749v.339c-2.076.169-3.135.677-3.135,2.033a10.446,10.446,0,0,0,.932,3.3l5.76,14.741,5.719-14.826a10.587,10.587,0,0,0,.72-3.133c0-1.313-.8-1.907-3.007-2.118v-.339h8.514v.339c-2.288.254-2.754.974-3.643,3.3L553.645,71.154l-7.582-19.146c.043,0-7.328,19.146-7.328,19.146Z" transform="translate(-343.583 -26.97)" fill="#3b3d3e" /> 8489 <path id="Path_88" data-name="Path 88" d="M649.672,67.539c2.753-.339,3.3-1.016,3.3-4.574V52.376c0-1.95-1.1-2.33-3.135-1.736v-.51l8.261-2.71V62.965c0,3.515.55,4.277,2.922,4.574v.339H649.672Zm2.8-27.066a2.844,2.844,0,0,1,3.008-2.8,2.8,2.8,0,1,1,0,5.591A2.871,2.871,0,0,1,652.467,40.473Z" transform="translate(-426.092 -24.711)" fill="#3b3d3e" /> 8490 <path id="Path_89" data-name="Path 89" d="M686.232,86.186c2.753-.339,3.176-1.1,3.176-4.574V71.53c0-2.838-1.059-2.88-3.008-2.33v-.508l8.133-2.584V70.26c2.076-2.033,4.321-4.025,7.2-4.025,3.219,0,5.336,2.118,5.336,5.8v9.573c0,3.558.466,4.277,3.008,4.574v.339H698.9v-.339c2.668-.339,3.049-.974,3.049-4.574V72.927c0-2.584-.974-3.812-3.092-3.812-1.652,0-3.008.974-4.321,2.161V81.612c0,3.515.466,4.277,2.88,4.574v.339H686.232Z" transform="translate(-450.07 -43.358)" fill="#3b3d3e" /> 8491 <path id="Path_90" data-name="Path 90" d="M758.857,77.108c0-5,3.431-10.632,9.319-10.632,5.76,0,8.725,3.94,8.725,7.963H763.6c0,5.338,2.88,9.278,7.032,9.278,2.118,0,4.575-.636,6.523-3.94l.339.169c-1.271,3.643-4.448,7.329-9.192,7.329C762.965,87.274,758.857,82.869,758.857,77.108Zm12.749-4.066c-.339-2.712-1.355-5.253-3.812-5.253-2.33,0-3.854,2.415-4.109,5.253Z" transform="translate(-497.702 -43.598)" fill="#3b3d3e" /> 8492 </g> 8493 </svg> 8494 8495 } 8496 8497 @helper RenderCloseButton() 8498 { 8499 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> 8500 <path id="Path_91" data-name="Path 91" d="M2.267,2.267a.908.908,0,0,1,1.285,0L12,10.715l8.447-8.449a.909.909,0,0,1,1.285,1.287L13.284,12l8.449,8.448a.909.909,0,0,1-1.287,1.285L12,13.284,3.552,21.734a.909.909,0,1,1-1.285-1.287L10.715,12,2.265,3.552a.908.908,0,0,1,0-1.285Z" transform="translate(-1.999 -1.999)" fill="#3b3d3e" fill-rule="evenodd" /> 8501 </svg> 8502 } 8503 8504 @helper SidemenuRenderCartUsps(string icon, string toptext, string bottomtext) 8505 { 8506 var svg = icon + ".svg"; 8507 8508 <div class="grid__col-12 grid__col-md-3"> 8509 <div class="grid grid--align-center u-justify-content--center border-right"> 8510 <div class="grid__col-2"> 8511 <img src="/Files/Images/SvgIcons/@svg" height="35" width="35" /> 8512 </div> 8513 <div class="grid__col-8"> 8514 <div class="u-block"> 8515 <strong>@toptext</strong> 8516 </div> 8517 <div class="u-block"> 8518 @bottomtext 8519 </div> 8520 </div> 8521 </div> 8522 </div> 8523 }</text> 8524 if (Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Tablet) 8525 { 8526 <text>@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 8527 8528 @using System 8529 @using System.Web 8530 @using System.Collections.Generic 8531 @using Dynamicweb.Rapido.Blocks.Extensibility 8532 @using Dynamicweb.Rapido.Blocks 8533 8534 @functions { 8535 BlocksPage tabletNavigationBlocksPage = BlocksPage.GetBlockPage("Master"); 8536 } 8537 8538 @{ 8539 bool mobileNavigationItemsHideSignIn = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("HideSignIn"); 8540 bool mobileHideCreateAccountLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideCreateAccount"); 8541 bool mobileHideMyProfileLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideProfile"); 8542 bool mobileHideMyOrdersLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideOrders"); 8543 bool mobileHideMySavedCardsLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideSavedCards"); 8544 bool mobileHideMyFavoritesLink = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("SignInHideFavorites"); 8545 bool tabletHideCustomerStockLink = false; 8546 8547 Block mobileNavigation = new Block() 8548 { 8549 Id = "TabletNavigation", 8550 SortId = 10, 8551 Template = TabletNavigation(), 8552 SkipRenderBlocksList = true 8553 }; 8554 tabletNavigationBlocksPage.Add(MasterBlockId.MasterTopSnippets, mobileNavigation); 8555 8556 if (Model.CurrentUser.ID > 0 && !mobileHideMyProfileLink) 8557 { 8558 Block mobileNavigationSignIn = new Block 8559 { 8560 Id = "MobileNavigationSignIn", 8561 SortId = 10, 8562 Template = RenderTabletNavigationSignIn() 8563 }; 8564 tabletNavigationBlocksPage.Add("TabletNavigation", mobileNavigationSignIn); 8565 } 8566 8567 Block mobileNavigationMenu = new Block 8568 { 8569 Id = "TabletNavigationMenu", 8570 SortId = 20, 8571 Template = RenderTabletNavigationMenu() 8572 }; 8573 tabletNavigationBlocksPage.Add("TabletNavigation", mobileNavigationMenu); 8574 8575 Block mobileNavigationActions = new Block 8576 { 8577 Id = "TabletNavigationActions", 8578 SortId = 30, 8579 Template = RenderTabletNavigationActions(), 8580 SkipRenderBlocksList = true 8581 }; 8582 tabletNavigationBlocksPage.Add("TabletNavigation", mobileNavigationActions); 8583 8584 if (!mobileNavigationItemsHideSignIn) 8585 { 8586 if (Model.CurrentUser.ID <= 0) 8587 { 8588 Block mobileNavigationSignInAction = new Block 8589 { 8590 Id = "TabletNavigationSignInAction", 8591 SortId = 10, 8592 Template = RenderTabletNavigationSignInAction() 8593 }; 8594 tabletNavigationBlocksPage.Add("TabletNavigationActions", mobileNavigationSignInAction); 8595 8596 if (!mobileHideCreateAccountLink) 8597 { 8598 Block mobileNavigationCreateAccountAction = new Block 8599 { 8600 Id = "TabletNavigationCreateAccountAction", 8601 SortId = 20, 8602 Template = RenderTabletNavigationCreateAccountAction() 8603 }; 8604 tabletNavigationBlocksPage.Add("TabletNavigationActions", mobileNavigationCreateAccountAction); 8605 } 8606 } 8607 else 8608 { 8609 if (!mobileHideMyOrdersLink) 8610 { 8611 Block mobileNavigationOrdersAction = new Block 8612 { 8613 Id = "TabletNavigationOrdersAction", 8614 SortId = 20, 8615 Template = RenderTabletNavigationOrdersAction() 8616 }; 8617 tabletNavigationBlocksPage.Add("TabletNavigationActions", mobileNavigationOrdersAction); 8618 } 8619 if (!mobileHideMyFavoritesLink) 8620 { 8621 Block mobileNavigationFavoritesAction = new Block 8622 { 8623 Id = "TabletNavigationFavoritesAction", 8624 SortId = 30, 8625 Template = RenderTabletNavigationFavoritesAction() 8626 }; 8627 tabletNavigationBlocksPage.Add("TabletNavigationActions", mobileNavigationFavoritesAction); 8628 } 8629 if (!mobileHideMySavedCardsLink) 8630 { 8631 Block mobileNavigationSavedCardsAction = new Block 8632 { 8633 Id = "TabletNavigationFavoritesAction", 8634 SortId = 30, 8635 Template = RenderTabletNavigationSavedCardsAction() 8636 }; 8637 tabletNavigationBlocksPage.Add("TabletNavigationActions", mobileNavigationSavedCardsAction); 8638 } 8639 8640 if (!tabletHideCustomerStockLink) 8641 { 8642 Block tabletNavigationCustomerStockAction = new Block 8643 { 8644 Id = "TabletNavigationCustomerStockAction", 8645 SortId = 31, 8646 Template = RenderTabletNavigationCustomerStockAction() 8647 }; 8648 tabletNavigationBlocksPage.Add("TabletNavigationActions", tabletNavigationCustomerStockAction); 8649 } 8650 8651 Block mobileNavigationSignOutAction = new Block 8652 { 8653 Id = "TabletNavigationSignOutAction", 8654 SortId = 40, 8655 Template = RenderTabletNavigationSignOutAction() 8656 }; 8657 tabletNavigationBlocksPage.Add("TabletNavigationActions", mobileNavigationSignOutAction); 8658 } 8659 } 8660 8661 if (Model.Languages.Count > 1) 8662 { 8663 Block mobileNavigationLanguagesAction = new Block 8664 { 8665 Id = "TabletNavigationLanguagesAction", 8666 SortId = 50, 8667 Template = RenderTabletNavigationLanguagesAction() 8668 }; 8669 tabletNavigationBlocksPage.Add("TabletNavigationActions", mobileNavigationLanguagesAction); 8670 } 8671 } 8672 8673 8674 @helper TabletNavigation() 8675 { 8676 List<Block> subBlocks = this.tabletNavigationBlocksPage.GetBlockListById("TabletNavigation").OrderBy(item => item.SortId).ToList(); 8677 string mobileTopDesign = Model.Area.Item.GetItem("Layout").GetItem("MobileTop").GetList("Design") != null ? Model.Area.Item.GetItem("Layout").GetItem("MobileTop").GetList("Design").SelectedValue : "nav-left"; 8678 string position = mobileTopDesign == "nav-left" || mobileTopDesign == "nav-search-left" ? "left" : "right"; 8679 8680 <!-- Trigger for mobile navigation --> 8681 <input type="checkbox" id="MobileNavTrigger" class="mobile-nav-trigger mobile-nav-trigger--@position" autocomplete="off" /> 8682 8683 <!-- Mobile navigation --> 8684 <nav class="mobile-navigation mobile-navigation--@position dw-mod js-mobile-navigation"> 8685 <div class="mobile-navigation__wrapper" id="mobileNavigationWrapper"> 8686 <div class="mobile-navigation-header"> 8687 <div class="mobile-navigation-header-topbar"> 8688 <p>@Translate("Smartpage:MobilMenu.headerText", "Brug for hjælp? +45 70 22 68 88")</p> 8689 <div class="mobile-navigation-header-close js-navigation-close"> 8690 <div class="mobile-navigation-header-cross"> 8691 <span></span> 8692 <span></span> 8693 </div> 8694 <p>@Translate("Smartpage:MobilMenu.CloseText", "Luk")</p> 8695 </div> 8696 </div> 8697 @RenderTabletNavigationSearchBar() 8698 </div> 8699 @RenderBlockList(subBlocks) 8700 </div> 8701 <div class="mobile-navigation-footer"> 8702 <ul> 8703 @foreach (var icon in Pageview.AreaSettings.GetItem("Custom").GetItem("CustomSettings").GetItems("HeaderUSP")) 8704 { 8705 <li> 8706 @if (!string.IsNullOrWhiteSpace(icon.GetString("Link"))) 8707 { 8708 <a href="@icon.GetString("Link")"><i class="fa fa-check"></i> @icon.GetString("Label")</a> 8709 } 8710 else 8711 { 8712 <i class="fa fa-check"></i> @icon.GetString("Label") 8713 } 8714 </li> 8715 } 8716 </ul> 8717 </div> 8718 </nav> 8719 8720 <label class="mobile-nav-trigger-off js-mobile-nav-trigger-off" for="MobileNavTrigger"></label> 8721 } 8722 8723 @helper RenderTabletNavigationSignIn() 8724 { 8725 int signInProfilePageId = GetPageIdByNavigationTag("SignInPage"); 8726 int myProfilePageId = GetPageIdByNavigationTag("CustomerProfile"); 8727 string linkStart = Model.CurrentUser.ID <= 0 ? "/Default.aspx?ID=" + signInProfilePageId + "&RedirectPageId=" : "/Default.aspx?ID="; 8728 string myProfilePageLink = linkStart + myProfilePageId; 8729 string userName = Model.CurrentUser.FirstName; 8730 if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(Model.CurrentUser.LastName)) 8731 { 8732 userName += " " + Model.CurrentUser.LastName; 8733 } 8734 if (string.IsNullOrEmpty(userName)) 8735 { 8736 userName = Model.CurrentUser.Name; 8737 } 8738 if (string.IsNullOrEmpty(userName)) 8739 { 8740 userName = Model.CurrentUser.UserName; 8741 } 8742 if (string.IsNullOrEmpty(userName)) 8743 { 8744 userName = Model.CurrentUser.Email; 8745 } 8746 8747 <ul class="menu menu-mobile"> 8748 <li class="menu-mobile__item"> 8749 <a href="@myProfilePageLink" class="menu-mobile__link dw-mod"><i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignInProfileIcon").SelectedValue menu-mobile__link-icon"></i> @userName</a> 8750 </li> 8751 </ul> 8752 } 8753 8754 @helper RenderTabletNavigationMenu() 8755 { 8756 bool isSlidesDesign = Model.Area.Item.GetItem("Layout").GetItem("MobileNavigation").GetList("Design").SelectedValue == "Slides"; 8757 string menuTemplate = isSlidesDesign ? "BaseMenuForMobileSlides.xslt" : "BaseMenuForMobileExpandable.xslt"; 8758 string levels = !String.IsNullOrEmpty(Model.Area.Item.GetItem("Layout").GetItem("MobileNavigation").GetString("Levels")) ? Model.Area.Item.GetItem("Layout").GetItem("MobileNavigation").GetString("Levels") : "3"; 8759 bool renderPagesInToolBar = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("RenderPagesInToolBar"); 8760 int startLevel = 0; 8761 8762 var navigationSettings = new Dynamicweb.Frontend.Navigation.NavigationSettings() 8763 { 8764 RootAreaId = 0, 8765 RootPageId = 0, 8766 RootNavigationTag = "main-menu", 8767 StartLevel = 1, 8768 StopLevel = 99, 8769 ExpandMode = Dynamicweb.Frontend.Navigation.ExpandMode.All 8770 }; 8771 8772 var navigationTemplate = "Navigation/SpViewModelNavigationMobile.cshtml"; 8773 @Navigation.RenderNavigation(navigationTemplate, navigationSettings) 8774 8775 8776 if (isSlidesDesign) 8777 { 8778 <script> 8779 function goToLevel(level) { 8780 document.getElementById('mobileNavigationWrapper').style.left = -(level * 100) + "%"; 8781 } 8782 8783 document.addEventListener('DOMContentLoaded', function () { 8784 goToLevel(document.getElementById('mobileNavigationWrapper').querySelectorAll('input[type=radio]:checked').length); 8785 }); 8786 </script> 8787 } 8788 8789 if (renderPagesInToolBar) 8790 { 8791 @RenderNavigation(new 8792 { 8793 id = "topToolsMobileNavigation", 8794 cssclass = "menu menu-mobile dwnavigation", 8795 template = "ToolsMenuForMobile.xslt" 8796 }) 8797 } 8798 } 8799 8800 @helper RenderTabletNavigationActions() 8801 { 8802 List<Block> subBlocks = this.tabletNavigationBlocksPage.GetBlockListById("TabletNavigationActions").OrderBy(item => item.SortId).ToList(); ; 8803 8804 <ul class="menu menu-mobile"> 8805 @RenderBlockList(subBlocks) 8806 </ul> 8807 } 8808 8809 @helper RenderTabletNavigationSignInAction() 8810 { 8811 <li class="menu-mobile__item mobile-navigation-login"> 8812 <label for="SignInModalTrigger" onclick="document.getElementById('MobileNavTrigger').checked = false;" class="menu-mobile__link dw-mod menu-mobile__link--highlighted"><i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignInProfileIcon").SelectedValue menu-mobile__link-icon"></i> @Translate("Sign in")</label> 8813 </li> 8814 } 8815 8816 @helper RenderTabletNavigationCreateAccountAction() 8817 { 8818 int createAccountPageId = GetPageIdByNavigationTag("CreateAccount"); 8819 8820 <li class="menu-mobile__item mobile-navigation-create-account"> 8821 <h3>@Translate("Smartpage:MobilMenu.CreateAccountHeading", "Opret bruger og få 100 DKK i opstartsbonus")</h3> 8822 <p>@Translate("Smartpage:MobilMenu.CreateAccountText", "(Gælder på dit næste køb)")</p> 8823 <a class="menu-mobile__link menu-mobile__link--highlighted dw-mod" href="/Default.aspx?ID=@createAccountPageId"><i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignInProfileIcon").SelectedValue menu-mobile__link-icon"></i> @Translate("Create account")</a> 8824 </li> 8825 } 8826 8827 @helper RenderTabletNavigationProfileAction() 8828 { 8829 int signInProfilePageId = GetPageIdByNavigationTag("SignInPage"); 8830 string linkStart = Model.CurrentUser.ID <= 0 ? "/Default.aspx?ID=" + signInProfilePageId + "&RedirectPageId=" : "/Default.aspx?ID="; 8831 int myProfilePageId = GetPageIdByNavigationTag("CustomerProfile"); 8832 string myProfilePageLink = linkStart + myProfilePageId; 8833 8834 <li class="menu-mobile__item"> 8835 <a href="@myProfilePageLink" class="menu-mobile__link menu-mobile__link--highlighted dw-mod"><i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignInProfileIcon").SelectedValue menu-mobile__link-icon"></i> @Translate("My Profile")</a> 8836 </li> 8837 } 8838 8839 @helper RenderTabletNavigationOrdersAction() 8840 { 8841 int signInProfilePageId = GetPageIdByNavigationTag("SignInPage"); 8842 string linkStart = Model.CurrentUser.ID <= 0 ? "/Default.aspx?ID=" + signInProfilePageId + "&RedirectPageId=" : "/Default.aspx?ID="; 8843 int myOrdersPageId = GetPageIdByNavigationTag("CustomerOrders"); 8844 string myOrdersPageLink = linkStart + myOrdersPageId; 8845 string ordersIcon = "fas fa-list"; 8846 8847 <li class="menu-mobile__item"> 8848 <a href="@myOrdersPageLink" class="menu-mobile__link menu-mobile__link--highlighted dw-mod"><i class="@ordersIcon menu-mobile__link-icon"></i> @Translate("My Orders")</a> 8849 </li> 8850 } 8851 8852 @helper RenderTabletNavigationFavoritesAction() 8853 { 8854 int signInProfilePageId = GetPageIdByNavigationTag("SignInPage"); 8855 string linkStart = Model.CurrentUser.ID <= 0 ? "/Default.aspx?ID=" + signInProfilePageId + "&RedirectPageId=" : "/Default.aspx?ID="; 8856 int myFavoritesPageId = GetPageIdByNavigationTag("CustomerFavorites"); 8857 string myFavoritesPageLink = linkStart + myFavoritesPageId; 8858 string favoritesIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon") != null ? "fas fa-" + Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("FavoriteIcon").SelectedValue : "fa fa-star"; 8859 8860 8861 <li class="menu-mobile__item"> 8862 <a href="@myFavoritesPageLink" class="menu-mobile__link menu-mobile__link--highlighted dw-mod"><i class="@favoritesIcon menu-mobile__link-icon"></i> @Translate("My Favorites")</a> 8863 </li> 8864 } 8865 8866 @helper RenderTabletNavigationSavedCardsAction() 8867 { 8868 int signInProfilePageId = GetPageIdByNavigationTag("SignInPage"); 8869 string linkStart = Model.CurrentUser.ID <= 0 ? "/Default.aspx?ID=" + signInProfilePageId + "&RedirectPageId=" : "/Default.aspx?ID="; 8870 int mySavedCardsPageId = GetPageIdByNavigationTag("SavedCards"); 8871 string mySavedCardsPageLink = linkStart + mySavedCardsPageId; 8872 string savedCardsIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SavedCards") != null ? "fas fa-" + Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SavedCards").SelectedValue : "fas fa-credit-card"; 8873 8874 <li class="menu-mobile__item"> 8875 <a href="@mySavedCardsPageLink" class="menu-mobile__link menu-mobile__link--highlighted dw-mod"><i class="@savedCardsIcon menu-mobile__link-icon"></i> @Translate("My Saved Cards")</a> 8876 </li> 8877 } 8878 8879 @helper RenderTabletNavigationCustomerStockAction() 8880 { 8881 int customerStockPageId = GetPageIdByNavigationTag("CustomerStockPage"); 8882 8883 <li class="menu-mobile__item"> 8884 <a class="menu-mobile__link menu-mobile__link--highlighted dw-mod" href="/Default.aspx?ID=@customerStockPageId"><i class="fal fa-clipboard-list menu-mobile__link-icon"></i> @Translate("Smartpage:SignInActions.CustomerStock", "Mit kundelager")</a> 8885 </li> 8886 } 8887 8888 @helper RenderTabletNavigationSignOutAction() 8889 { 8890 int pageId = Model.TopPage.ID; 8891 string signOutIcon = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignOutIcon") != null ? "fas fa-" + Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SignOutIcon").SelectedValue : "far fa-sign-out-alt"; 8892 8893 <li class="menu-mobile__item"> 8894 <a class="menu-mobile__link menu-mobile__link--highlighted dw-mod" href="/Admin/Public/ExtranetLogoff.aspx?ID=@pageId" onclick="RememberState.SetCookie('useAnotherAddress', false)"><i class="@signOutIcon menu-mobile__link-icon"></i> @Translate("Sign out")</a> 8895 </li> 8896 } 8897 8898 @helper RenderTabletNavigationLanguagesAction() 8899 { 8900 bool isSlidesDesign = Model.Area.Item.GetItem("Layout").GetItem("MobileNavigation").GetList("Design").SelectedValue == "Slides"; 8901 8902 string selectedLanguage = ""; 8903 foreach (var lang in Model.Languages) 8904 { 8905 if (lang.IsCurrent) 8906 { 8907 selectedLanguage = lang.Name; 8908 } 8909 } 8910 8911 <li class="menu-mobile__item dw-mod menu-mobile__item-language"> 8912 @if (isSlidesDesign) 8913 { 8914 <input id="MobileMenuCheck_Language" type="radio" class="expand-trigger" name="mobile-menu-level-1" onclick="goToLevel(1);"> 8915 } 8916 else 8917 { 8918 <input id="MobileMenuCheck_Language" type="checkbox" class="expand-trigger"> 8919 } 8920 <div class="menu-mobile__link__wrap"> 8921 <label for="MobileMenuCheck_Language" class="menu-mobile__link menu-mobile__link--highlighted dw-mod"><i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("LanguageIcon").SelectedValue menu-mobile__link-icon"></i> @selectedLanguage</label> 8922 <label for="MobileMenuCheck_Language" class="menu-mobile__trigger"></label> 8923 </div> 8924 <ul class="menu-mobile menu-mobile__submenu expand-menu"> 8925 @if (isSlidesDesign) 8926 { 8927 <li class="menu-mobile__item dw-mod"> 8928 <div class="menu-mobile__link__wrap"> 8929 <input id="MobileMenuCheck_Language_back" type="radio" class="expand-trigger" name="mobile-menu-level-1" onclick="goToLevel(0);" /> 8930 <label for="MobileMenuCheck_Language_back" class="menu-mobile__trigger menu-mobile__trigger--back"></label> 8931 <label for="MobileMenuCheck_Language_back" class="menu-mobile__link dw-mod ">@Translate("Back")</label> 8932 </div> 8933 </li> 8934 } 8935 @foreach (var lang in Model.Languages) 8936 { 8937 <li class="menu-mobile__item dw-mod"> 8938 <a class="menu-mobile__link menu-mobile__link--highlighted dw-mod menu-mobile__link--level-1" href="/Default.aspx?ID=@lang.Page.ID">@lang.Name</a> 8939 </li> 8940 } 8941 </ul> 8942 </li> 8943 } 8944 8945 8946 @helper RenderTabletNavigationSearchBar() 8947 { 8948 string searchFeedId = string.Empty; 8949 string searchSecondFeedId = string.Empty; 8950 int groupsFeedId; 8951 string productsSearchId = Converter.ToString(GetPageIdByNavigationTag("ProductSearchFeed")); 8952 int productsPageId = GetPageIdByNavigationTag("ProductsPage"); 8953 string contentSearchPageLink = GetPageIdByNavigationTag("ContentSearchResults") + "&Areaid=" + Model.Area.ID; 8954 string resultPageLink; 8955 string searchPlaceholder; 8956 string searchType = "product-search"; 8957 string searchTemplate; 8958 string searchContentTemplate = ""; 8959 string searchValue = HttpContext.Current.Request.QueryString.Get("Search") ?? ""; 8960 bool showGroups = true; 8961 8962 if (Model.Area.Item.GetItem("Layout").GetList("TopSearch").SelectedValue == "contentSearch") 8963 { 8964 searchFeedId = GetPageIdByNavigationTag("ContentSearchFeed") + "&Areaid=" + Model.Area.ID + "&pagesOnly=true"; 8965 resultPageLink = contentSearchPageLink; 8966 searchPlaceholder = Translate("Search page"); 8967 groupsFeedId = 0; 8968 searchType = "content-search"; 8969 searchTemplate = "SearchPagesTemplate"; 8970 showGroups = false; 8971 } 8972 else if (Model.Area.Item.GetItem("Layout").GetList("TopSearch").SelectedValue == "combinedSearch") 8973 { 8974 searchFeedId = productsPageId + "&feed=true"; 8975 searchSecondFeedId = GetPageIdByNavigationTag("ContentSearchFeed") + "&Areaid=" + Model.Area.ID + "&pagesOnly=true"; 8976 resultPageLink = Converter.ToString(productsPageId); 8977 searchPlaceholder = Translate("Search products or pages"); 8978 groupsFeedId = GetPageIdByNavigationTag("ProductGroupsFeed"); 8979 searchType = "combined-search"; 8980 searchTemplate = "SearchProductsTemplateWrap"; 8981 searchContentTemplate = "SearchPagesTemplateWrap"; 8982 showGroups = Model.Area.Item.GetItem("Layout").GetBoolean("ShowGroupsSelector"); 8983 } 8984 else 8985 { 8986 resultPageLink = Converter.ToString(productsPageId); 8987 searchFeedId = productsSearchId + "&feed=true"; 8988 groupsFeedId = GetPageIdByNavigationTag("ProductGroupsFeed"); 8989 searchPlaceholder = Translate("Search products"); 8990 searchTemplate = "SearchResultsTypeAheadMobile"; 8991 searchType = "product-search"; 8992 showGroups = Model.Area.Item.GetItem("Layout").GetBoolean("ShowGroupsSelector"); 8993 } 8994 8995 <input type="checkbox" id="MobileSearchTrigger" class="mobile-search-trigger" /> 8996 8997 <div class="main-navigation-mobile mobile-navigation-header-search typeahead-mobile dw-mod"> 8998 <div class="center-container top-container__center-container u-no-padding dw-mod"> 8999 <div class="grid"> 9000 <div class="typeahead-mobile__search-field tablet dw-mod u-no-padding-x js-typeahead" data-page-size="@(searchType == "combined-search" ? 4 : 8)" id="MobileProductSearch" data-search-feed-id="@searchFeedId" data-search-second-feed-id="@searchSecondFeedId" data-result-page-id="@resultPageLink" data-search-type="@searchType"> 9001 <div class="mobile-navigation-header-search"> 9002 <i class="far fa-search"></i> 9003 <input id="TypeaheadSearchFieldMobile" type="text" class="js-typeahead-search-field js-tablet-search u-w160px u-no-margin" data-shop-id="@Pageview.Area.EcomShopId" data-area-id="@Dynamicweb.Core.Converter.ToString(Pageview.AreaID)" placeholder="@HttpUtility.HtmlAttributeEncode(searchPlaceholder)" value="@HttpUtility.HtmlAttributeEncode(searchValue)"> 9004 <form class="u-full-width" action="@Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(productsPageId)" id="SearchSubmitForm"> 9005 <input type="text" class="typeahead-autocomplete js-typeahead-autocomplete u-no-margin" disabled /> 9006 </form> 9007 </div> 9008 <div class="tablet-search js-tablet-search-container u-min-w220px u-full-width"> 9009 <span class="typeahead-search-overlay typeahead-search-container js-handlebars-root js-typeahead-search-content dw-mod" id="MobileProductSearchBarContent" data-template="@searchTemplate" data-json-feed="/Default.aspx?ID=@searchFeedId&feedType=productsOnly" data-init-onload="false"></span> 9010 </div> 9011 </div> 9012 </div> 9013 </div> 9014 </div> 9015 }</text> 9016 } 9017 } 9018 } 9019 9020 @using Custom.PhilipsonWine.Security.Helpers 9021 @using Dynamicweb.Frontend 9022 9023 @functions { 9024 public class NewsletterSignupHelperContext 9025 { 9026 public PageView Pageview { get; set; } 9027 public Func<string, int> GetPageIdByNavigationTag { get; set; } 9028 public Func<string, string, string> Translate { get; set; } 9029 } 9030 } 9031 9032 @helper RenderNewsletterSignUp(NewsletterSignupHelperContext context, string origin, string listId, string customThankYouMessage = "") 9033 { 9034 int signupForNewsletterPageId = context.GetPageIdByNavigationTag("SignupForNewsletter"); 9035 if (signupForNewsletterPageId > 0 && !string.IsNullOrEmpty(listId)) 9036 { 9037 bool isMobile = context.Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Mobile; 9038 string translationOrigin = "Custom:" + (isMobile ? "Mobile" : "") + origin + "Signup"; 9039 string actionUrl = "/Default.aspx?ID=" + signupForNewsletterPageId; 9040 string placeholderName = context.Translate(translationOrigin + ".Name", "Skriv dit navn"); 9041 string placeholderEmail = context.Translate(translationOrigin + ".Email", "Skriv din email"); 9042 string url = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Host + HttpContext.Current.Request.RawUrl; 9043 string recaptchaSiteKey = RecaptchaHelper.RecaptchaSiteKey; 9044 var user = Dynamicweb.Security.UserManagement.User.GetCurrentFrontendUser(); 9045 string userName = user != null ? user.Name : ""; 9046 string userEmail = user != null ? user.Email : ""; 9047 string wrapperClass = (isMobile ? "mobile-" : "") + origin.ToLower() + "-newsletter-signup-container"; 9048 int offersPageId = context.GetPageIdByNavigationTag("OffersPage"); 9049 9050 <div class="@wrapperClass js-signup-form-container"> 9051 <form class="show-signup-form signup-form js-signup-form" method="post" action="@actionUrl"> 9052 <div class="signup-form-container"> 9053 <div> 9054 <p class="header-title">@context.Translate(translationOrigin + ".HeaderTitle", "Gå ikke glip af de bedste tilbud!")</p> 9055 <p class="header-text">@context.Translate(translationOrigin + ".HeaderText", "Tilmeld dig vores nyhedsbrev")</p> 9056 </div> 9057 <input required name="name" type="text" value="@HttpUtility.HtmlAttributeEncode(userName)" placeholder="@HttpUtility.HtmlAttributeEncode(placeholderName)" aria-label="@HttpUtility.HtmlAttributeEncode(placeholderName)" autocomplete="given-name" /> 9058 <input required name="email" type="email" value="@HttpUtility.HtmlAttributeEncode(userEmail)" placeholder="@HttpUtility.HtmlAttributeEncode(placeholderEmail)" aria-label="@HttpUtility.HtmlAttributeEncode(placeholderEmail)" autocomplete="email" /> 9059 <input name="origin" type="hidden" value="@HttpUtility.HtmlAttributeEncode(context.Translate(translationOrigin + ".Tracking.Origin", "Website" + origin + "Signup"))" /> 9060 <input name="url" type="hidden" value="@HttpUtility.HtmlAttributeEncode(url)" /> 9061 <input name="device" type="hidden" value="@HttpUtility.HtmlAttributeEncode(context.Pageview.Device.ToString())" /> 9062 <input name="listId" type="hidden" value="@HttpUtility.HtmlAttributeEncode(listId)" /> 9063 <input class="js-newsletter-signup-page-id" name="pageId" type="hidden" value="@HttpUtility.HtmlAttributeEncode(Dynamicweb.Core.Converter.ToString(signupForNewsletterPageId))" /> 9064 </div> 9065 @if (RecaptchaHelper.RecaptchaActivated) 9066 { 9067 <input class="js-recaptcha-token-input" name="recaptchaToken" type="hidden" /> 9068 <input name="recaptchaSiteKey" type="hidden" value="@HttpUtility.HtmlAttributeEncode(recaptchaSiteKey)" /> 9069 <input name="recaptchaAction" type="hidden" value="@HttpUtility.HtmlAttributeEncode(context.Translate(translationOrigin + ".ReCAPTCHA.ActionValue", (isMobile ? "mobile_" : "") + origin.ToLower() + "_signup_newsletter"))" /> 9070 <button class="g-recaptcha js-g-recaptcha" data-sitekey="@HttpUtility.HtmlAttributeEncode(recaptchaSiteKey)" data-action="@HttpUtility.HtmlAttributeEncode(context.Translate(translationOrigin + ".ReCAPTCHA.ActionValue", (isMobile ? "mobile_" : "") + origin.ToLower() + "_signup_newsletter"))">@context.Translate(translationOrigin + ".Button", "Tilmeld")</button> 9071 } 9072 else 9073 { 9074 <button>@context.Translate(translationOrigin + ".Button", "Tilmeld")</button> 9075 } 9076 </form> 9077 <div class="hide-signup-form submitted-form-message js-submitted-form-message"> 9078 <div> 9079 <p class="header-title">@context.Translate(translationOrigin + ".Submitted.HeaderTitle", "Tak for din tilmelding!")</p> 9080 @if (!string.IsNullOrEmpty(customThankYouMessage)) 9081 { 9082 <p class="header-text">@customThankYouMessage</p> 9083 } 9084 else 9085 { 9086 <p class="header-text">@context.Translate(translationOrigin + ".Submitted.HeaderText", "Du er nu tilmeldt vores nyhedsbrev og er en af de første til at modtage vores nye og spændende vintilbud.")</p> 9087 } 9088 </div> 9089 <div class="submitted-form-message-links"> 9090 <a href="/">@context.Translate(translationOrigin + ".Submitted.FrontPage", "Gå til forsiden")</a> 9091 @if (offersPageId > 0) 9092 { 9093 <a href="@Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?Id=" + offersPageId)">@context.Translate(translationOrigin + ".Submitted.AllOffers", "Se alle tilbud")</a> 9094 } 9095 </div> 9096 <div class="u-hidden u-pointer u-margin-top--lg js-show-signup-form-button">@context.Translate(translationOrigin + ".Submitted.ShowSignupForm", "Se formularen igen")</div> 9097 </div> 9098 </div> 9099 } 9100 } 9101 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 9102 9103 @using System 9104 @using System.Web 9105 @using Dynamicweb.Rapido.Blocks.Extensibility 9106 @using Dynamicweb.Rapido.Blocks 9107 @using Dynamicweb.Rapido.Blocks.Components.General 9108 @using Dynamicweb.Frontend 9109 @using Dynamicweb.Core 9110 9111 @functions { 9112 int impersonationPageId; 9113 string impersonationLayout; 9114 int impersonationFeed; 9115 Block impersonationBar; 9116 bool businessContactImpersonation; 9117 9118 string GetUserNameFromParams(string firstName, string middleName, string lastName, string name, string email, string userName) 9119 { 9120 string username = ""; 9121 9122 if (!string.IsNullOrEmpty(firstName) && !string.IsNullOrEmpty(lastName)) 9123 { 9124 username = firstName + " " + (!string.IsNullOrEmpty(middleName) ? middleName + " " : "") + lastName; 9125 } 9126 else if (!string.IsNullOrEmpty(name)) 9127 { 9128 username = name; 9129 } 9130 else if (!string.IsNullOrEmpty(email)) 9131 { 9132 username = email; 9133 } 9134 else 9135 { 9136 username = userName; 9137 } 9138 return username; 9139 } 9140 9141 string GetUserName(UserViewModel user) 9142 { 9143 return GetUserNameFromParams(user.FirstName, user.MiddleName, user.LastName, user.Name, user.Email, user.UserName); 9144 } 9145 9146 string GetUserName(Dynamicweb.Security.UserManagement.User user) 9147 { 9148 return GetUserNameFromParams(user.FirstName, user.MiddleName, user.LastName, user.Name, user.Email, user.UserName); 9149 } 9150 } 9151 9152 @{ 9153 impersonationPageId = GetPageIdByNavigationTag("Impersonation"); 9154 impersonationLayout = Model.Area.Item.GetItem("Ecommerce").GetList("ImpersonationLayout") != null ? Model.Area.Item.GetItem("Ecommerce").GetList("ImpersonationLayout").SelectedValue : "bar"; 9155 impersonationFeed = GetPageIdByNavigationTag("UsersFeed"); 9156 9157 businessContactImpersonation = Pageview.User?.CurrentSecondaryUser != null ? Converter.ToBoolean(Pageview.User.CurrentSecondaryUser.CustomFieldValues.FirstOrDefault(x => x.CustomField.SystemName == "AccessUser_SpBcImpersonator")?.Value) : Converter.ToBoolean(Pageview.User?.CustomFieldValues.FirstOrDefault(x => x.CustomField.SystemName == "AccessUser_SpBcImpersonator")?.Value); 9158 9159 9160 if (Model.CurrentUser.ID > 0 && Model.HasSecondaryUsers) 9161 { 9162 impersonationBar = new Block 9163 { 9164 Id = "ImpersonationBar", 9165 SortId = 50, 9166 Template = RenderImpersonation(), 9167 SkipRenderBlocksList = true, 9168 Design = new Design 9169 { 9170 Size = "auto-width", 9171 HidePadding = true, 9172 RenderType = RenderType.Column 9173 } 9174 }; 9175 9176 if (impersonationLayout == "top-bar") 9177 { 9178 impersonationBar.SortId = 9; 9179 } 9180 9181 Block impersonationContent = new Block 9182 { 9183 Id = "ImpersonationContent", 9184 SortId = 20 9185 }; 9186 9187 if (Model.CurrentSecondaryUser != null && Model.CurrentSecondaryUser.ID > 0) 9188 { 9189 //Render stop impersonation view 9190 impersonationContent.Template = RenderStopImpersonationView(); 9191 9192 9193 Modal stopImpersonation = new Modal 9194 { 9195 Id = "StopImpersonation", 9196 Heading = new Heading 9197 { 9198 Level = 2, 9199 Title = Translate("Sign out"), 9200 Icon = new Icon 9201 { 9202 Name = "fa-sign-out", 9203 Prefix = "fas", 9204 LabelPosition = IconLabelPosition.After 9205 } 9206 }, 9207 Width = ModalWidth.Sm, 9208 BodyTemplate = RenderStopImpersonationForm() 9209 }; 9210 9211 Block stopImpersonationBlock = new Block 9212 { 9213 Id = "StopImpersonationBlock", 9214 SortId = 10, 9215 Component = stopImpersonation 9216 }; 9217 impersonationBar.BlocksList.Add(stopImpersonationBlock); 9218 } 9219 else 9220 { 9221 //Render main view 9222 switch (impersonationLayout) 9223 { 9224 case "right-lower-box": 9225 impersonationContent.BlocksList.Add( 9226 new Block 9227 { 9228 Id = "RightLowerBoxHeader", 9229 SortId = 10, 9230 Component = new Heading 9231 { 9232 Level = 5, 9233 Title = Translate("View the list of users you can sign in as"), 9234 CssClass = "impersonation-text" 9235 } 9236 } 9237 ); 9238 impersonationContent.BlocksList.Add( 9239 new Block 9240 { 9241 Id = "RightLowerBoxContent", 9242 SortId = 20, 9243 Template = RenderImpersonationControls() 9244 } 9245 ); 9246 break; 9247 case "right-lower-bar": 9248 impersonationContent.BlocksList.Add( 9249 new Block 9250 { 9251 Id = "RightLowerBarContent", 9252 SortId = 10, 9253 Template = RenderImpersonationControls() 9254 } 9255 ); 9256 break; 9257 case "bar": 9258 default: 9259 impersonationContent.BlocksList.Add( 9260 new Block 9261 { 9262 Id = "ViewListLink", 9263 SortId = 20, 9264 Template = RenderViewListLink() 9265 } 9266 ); 9267 impersonationContent.BlocksList.Add( 9268 new Block 9269 { 9270 Id = "BarTypeaheadSearch", 9271 SortId = 30, 9272 Template = RenderTypeaheadSearch() 9273 } 9274 ); 9275 break; 9276 } 9277 } 9278 impersonationBar.BlocksList.Add(impersonationContent); 9279 9280 impersonationBar.BlocksList.Add( 9281 new Block 9282 { 9283 Id = "ImpersonationSearchTemplates", 9284 SortId = 30, 9285 Template = RenderSearchResultTemplate() 9286 } 9287 ); 9288 if (impersonationLayout != "bar" && impersonationLayout != "top-bar") 9289 { 9290 impersonationBar.BlocksList.Add( 9291 new Block 9292 { 9293 Id = "ImpersonationSearchScripts", 9294 SortId = 40, 9295 Template = RenderSearchScripts() 9296 } 9297 ); 9298 } 9299 BlocksPage.GetBlockPage("Master").Add("MasterHeader", impersonationBar); 9300 } 9301 } 9302 9303 @helper RenderImpersonation() 9304 { 9305 List<Block> subBlocks = impersonationBar.BlocksList.OrderBy(item => item.SortId).ToList(); 9306 <input type="checkbox" class="impersonation-trigger js-remember-state" id="ImpersonationMinimizeTrigger" /> 9307 <div class="impersonation impersonation--@(impersonationLayout)-layout dw-mod" id="Impersonation"> 9308 @if (impersonationLayout == "right-lower-box") 9309 { 9310 @RenderRightLowerBoxHeader() 9311 } 9312 <div class="center-container top-container__center-container impersonation__container @(impersonationLayout != "bar" && impersonationLayout != "top-bar" ? "impersonation__container--box" : "") dw-mod"> 9313 @*Impersonation*@ 9314 @RenderBlockList(subBlocks) 9315 </div> 9316 </div> 9317 } 9318 9319 @helper RenderRightLowerBoxHeader() 9320 { 9321 <div class="impersonation__header dw-mod"> 9322 <div class="impersonation__title">@Translate("Impersonation")</div> 9323 <label for="ImpersonationMinimizeTrigger" class="btn btn--impersonation impersonation__minimize-btn dw-mod" onclick="this.blur();"> 9324 @Render(new Icon 9325 { 9326 Prefix = "fas", 9327 Name = "fa-window-minimize" 9328 }) 9329 </label> 9330 </div> 9331 } 9332 9333 @helper RenderStopImpersonationView() 9334 { 9335 string secondaryUserName = GetUserName(Model.CurrentSecondaryUser); 9336 string userName = GetUserName(Pageview.User); 9337 string impersonationText = "<span class=\"impersonation-light-text dw-mod\">" + Translate("Logged in as") + "</span> <b>" + secondaryUserName + "</b> <span class=\"impersonation-light-text dw-mod\">" + Translate("by") + "</span> <b>" + userName + "</b> "; 9338 9339 if (businessContactImpersonation) 9340 { 9341 impersonationText = "<span class=\"impersonation-light-text dw-mod\">" + Translate("Smartpage:ImpersonationBar.BuyingOnBehalfOf", "Du køber på vegne af") + "</span> <b>" + Model.CurrentUser.Company + "</b>"; 9342 } 9343 9344 impersonationText = !businessContactImpersonation ? "<span class=\"impersonation-light-text dw-mod\">" + Translate("Logged in as") + "</span> <b>" + userName + "</b> <span class=\"impersonation-light-text dw-mod\">" + Translate("by") + "</span> <b>" + secondaryUserName + "</b> " : impersonationText; 9345 9346 if (impersonationLayout == "right-lower-box") 9347 { 9348 <div class="u-margin-bottom--lg u-ta-center"> 9349 @impersonationText 9350 </div> 9351 <div class="u-margin-bottom--lg u-ta-center"> 9352 @RenderSwitchAccountButton() 9353 </div> 9354 @RenderStopImpersonationButton() 9355 } 9356 else 9357 { 9358 <div class="grid grid--align-center impersonation__stop-wrap"> 9359 <div class="impersonation-bar-item dw-mod"> 9360 @impersonationText 9361 </div> 9362 <div class="impersonation-bar-item dw-mod"> 9363 @RenderSwitchAccountButton() 9364 </div> 9365 <div class="impersonation-bar-item dw-mod"> 9366 @if (businessContactImpersonation) 9367 { 9368 @RenderStopImpersonation() 9369 } 9370 else 9371 { 9372 @RenderStopImpersonationButton() 9373 } 9374 </div> 9375 </div> 9376 } 9377 } 9378 9379 @helper RenderStopImpersonation() 9380 { 9381 int pageId = Model.TopPage.ID; 9382 <form method="post" class="u-no-margin"> 9383 @Render(new Button 9384 { 9385 ButtonType = ButtonType.Submit, 9386 ButtonLayout = ButtonLayout.LinkClean, 9387 Title = businessContactImpersonation ? Translate("Smartpage:Impersonation.DeselectCustomer", "Fravælg kunde") : Translate("Stop impersonation"), 9388 Href = "/Default.aspx?ID=" + pageId, 9389 CssClass = "btn--full", 9390 Icon = new Icon 9391 { 9392 Name = "fa-sign-out", 9393 Prefix = "fal", 9394 LabelPosition = IconLabelPosition.After 9395 }, 9396 Name = "DwExtranetRemoveSecondaryUser" 9397 }) 9398 </form> 9399 } 9400 9401 @helper RenderSwitchAccountButton() 9402 { 9403 @Render(new Button 9404 { 9405 Href = "/Default.aspx?ID=" + impersonationPageId, 9406 ButtonLayout = ButtonLayout.LinkClean, 9407 Title = businessContactImpersonation ? Translate("Smartpage:Impersonation.ChangeCustomer", "Vælg anden kunde") : Translate("Switch account"), 9408 Icon = new Icon 9409 { 9410 Name = "fa-users", 9411 Prefix = "fal", 9412 LabelPosition = IconLabelPosition.After 9413 }, 9414 CssClass = "u-no-margin u-color-inherit" 9415 }) 9416 } 9417 9418 @helper RenderStopImpersonationForm() 9419 { 9420 string secondaryUserName = GetUserName(Model.CurrentSecondaryUser); 9421 string userName = GetUserName(Pageview.User); 9422 int pageId = Model.TopPage.ID; 9423 9424 <div class="u-align-center u-margin-bottom-10px u-font-size--sm">@Translate("Smartpage:Impersonation.DeselectCustomerBeforeLogoff", "Du skal først fravælge den valgte kunde før du kan logge ud")</div> 9425 9426 <form method="post" class="u-no-margin"> 9427 @if (businessContactImpersonation) 9428 { 9429 @Render(new Button 9430 { 9431 ButtonType = ButtonType.Submit, 9432 ButtonLayout = ButtonLayout.Secondary, 9433 Title = Translate("Smartpage:Impersonation.DeselectCustomer", "Fravælg kunde"), 9434 Href = "/Default.aspx?ID=" + impersonationPageId, 9435 CssClass = "btn--full", 9436 Name = "DwExtranetRemoveSecondaryUser" 9437 }) 9438 } 9439 else 9440 { 9441 @Render(new Button 9442 { 9443 ButtonType = ButtonType.Submit, 9444 ButtonLayout = ButtonLayout.Secondary, 9445 Title = Translate("Sign out as") + " " + userName, 9446 Href = "/Default.aspx?ID=" + impersonationPageId, 9447 CssClass = "btn--full", 9448 Name = "DwExtranetRemoveSecondaryUser" 9449 }) 9450 } 9451 </form> 9452 } 9453 9454 @helper RenderStopImpersonationButton() 9455 { 9456 @Render(new Button 9457 { 9458 ButtonType = ButtonType.Button, 9459 ButtonLayout = ButtonLayout.LinkClean, 9460 Title = Translate("Sign out"), 9461 Icon = new Icon 9462 { 9463 Name = "fa-sign-out", 9464 Prefix = "fal", 9465 LabelPosition = IconLabelPosition.After 9466 }, 9467 OnClick = "document.getElementById('StopImpersonationModalTrigger').checked = true", 9468 CssClass = "u-no-margin" 9469 }) 9470 } 9471 9472 @helper RenderImpersonationControls() 9473 { 9474 <div class="impersonation__controls"> 9475 @RenderViewListLink() 9476 @RenderSearchBox() 9477 </div> 9478 @RenderResultsList() 9479 } 9480 9481 @helper RenderViewListLink() 9482 { 9483 string title = impersonationLayout == "right-lower-box" ? Translate("View the list") : Translate("View the list of users you can sign in as"); 9484 9485 if (businessContactImpersonation) 9486 { 9487 title = Translate("Smartpage:ImpersonationBar.ViewUsersList", "Vis listen med kunder du kan købe på vegne af"); 9488 } 9489 9490 string buttonClasses = impersonationLayout == "right-lower-box" ? "impersonation__button btn btn--impersonation" : "impersonation__link impersonation__link"; 9491 9492 @Render(new Link 9493 { 9494 ButtonLayout = ButtonLayout.None, 9495 Title = title, 9496 Href = "/Default.aspx?ID=" + impersonationPageId, 9497 CssClass = buttonClasses 9498 }) 9499 } 9500 9501 @helper RenderSearchBox() 9502 { 9503 <div class="impersonation__search-wrap"> 9504 <input placeholder="@Translate("Search users")" type="text" class="impersonation__search-field dw-mod" onkeyup="searchKeyUpHandler(event)" id="ImpersonationBoxSearchField"> 9505 <div id="ImpersonationBoxSearchFind" class="impersonation__search-icon dw-mod" onclick="updateResults(document.getElementById('ImpersonationBoxSearchField').value)"> 9506 <i class="fal fa-search"></i> 9507 </div> 9508 <div id="ImpersonationBoxSearchClear" class="impersonation__search-icon u-hidden dw-mod" onclick="clearResults();"> 9509 <i class="fal fa-times"></i> 9510 </div> 9511 </div> 9512 } 9513 9514 @helper RenderTypeaheadSearch() 9515 { 9516 <div class="typeahead u-ta-right impersonation__typeahead js-typeahead dw-mod" id="ImpersonationSearchBar" 9517 data-page-size="5" 9518 data-search-feed-id="@impersonationFeed" 9519 data-result-page-id="@impersonationPageId" 9520 data-search-type="user-search" 9521 data-search-parameter-name="q"> 9522 9523 <div class="typeahead-search-field"> 9524 <input type="text" class="u-no-margin u-full-width js-typeahead-search-field" placeholder="@HttpUtility.HtmlAttributeEncode(businessContactImpersonation ? Translate("Search customers") : Translate("Search users"))"> 9525 <ul class="dropdown dropdown--absolute-position u-min-w220px u-full-width js-handlebars-root js-typeahead-search-content dw-mod" id="ImpersonationSearchBarContent" data-template="ImpersonationSearchResult" data-json-feed="/Default.aspx?ID=@impersonationFeed" data-init-onload="false"></ul> 9526 </div> 9527 </div> 9528 } 9529 9530 @helper RenderResultsList() 9531 { 9532 <ul id="ImpersonationBoxSearchResults" class="impersonation__search-results js-handlebars-root dw-mod" data-template="ImpersonationSearchResult" data-json-feed="/Default.aspx?ID=@impersonationFeed" data-init-onload="false" data-preloader="minimal"></ul> 9533 } 9534 9535 @helper RenderSearchResultTemplate() 9536 { 9537 <script id="ImpersonationSearchResult" type="text/x-template"> 9538 {{#.}} 9539 {{#Users}} 9540 <li class="impersonation__search-results-item impersonation-user"> 9541 <form method="post" class="impersonation-user__form" name="account{{id}}"> 9542 <input type="hidden" id="DWExtranetSecondaryUserSelector" name="DWExtranetSecondaryUserSelector" value="{{id}}"> 9543 @if (businessContactImpersonation) 9544 { 9545 <div class="impersonation-user__info"> 9546 <div class="impersonation-user__name">{{company}}</div> 9547 <div class="impersonation-user__number">{{customerNumber}}</div> 9548 </div> 9549 9550 @Render(new Button 9551 { 9552 ButtonType = ButtonType.Submit, 9553 ButtonLayout = ButtonLayout.Secondary, 9554 Title = Translate("Smartpage:Impersonation.SelectCustomer", "Vælg kunde"), 9555 CssClass = "impersonation-user__sign-in-btn u-pull--right u-no-margin" 9556 }); 9557 } 9558 else 9559 { 9560 <div class="impersonation-user__info"> 9561 <div class="impersonation-user__name">{{userName}}</div> 9562 <div class="impersonation-user__number">{{customerNumber}}</div> 9563 </div> 9564 9565 @Render(new Button 9566 { 9567 ButtonType = ButtonType.Submit, 9568 ButtonLayout = ButtonLayout.Secondary, 9569 Title = Translate("Sign in as"), 9570 CssClass = "impersonation-user__sign-in-btn u-pull--right u-no-margin" 9571 }); 9572 } 9573 </form> 9574 </li> 9575 {{/Users}} 9576 {{#unless Users}} 9577 <li class="impersonation__search-results-item impersonation__search-results-item--not-found"> 9578 @Translate("Your search gave 0 results") 9579 </li> 9580 {{/unless}} 9581 {{/.}} 9582 </script> 9583 } 9584 9585 @helper RenderSearchScripts() 9586 { 9587 <script> 9588 let inputDelayTimer; 9589 function searchKeyUpHandler(e) { 9590 clearTimeout(inputDelayTimer); 9591 let value = e.target.value; 9592 if (value != "") { 9593 inputDelayTimer = setTimeout(function () { 9594 updateResults(value); 9595 }, 500); 9596 } else { 9597 clearResults(); 9598 } 9599 }; 9600 9601 function updateResults(value) { 9602 if (value == "") { 9603 return null; 9604 } 9605 HandlebarsBolt.UpdateContent("ImpersonationBoxSearchResults", "/Default.aspx?ID=@impersonationFeed&q=" + value); 9606 document.getElementById("ImpersonationBoxSearchFind").classList.add("u-hidden"); 9607 document.getElementById("ImpersonationBoxSearchClear").classList.remove("u-hidden"); 9608 } 9609 9610 function clearResults() { 9611 document.getElementById("ImpersonationBoxSearchField").value = ""; 9612 HandlebarsBolt.CleanContainer("ImpersonationBoxSearchResults"); 9613 document.getElementById("ImpersonationBoxSearchFind").classList.remove("u-hidden"); 9614 document.getElementById("ImpersonationBoxSearchClear").classList.add("u-hidden"); 9615 } 9616 </script> 9617 } 9618 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 9619 9620 @using System 9621 @using System.Web 9622 @using System.Collections.Generic 9623 @using Dynamicweb.Rapido.Blocks.Extensibility 9624 @using Dynamicweb.Rapido.Blocks 9625 9626 @{ 9627 BlocksPage miniCartBlocksPage = BlocksPage.GetBlockPage("Master"); 9628 string orderlinesView = Model.Area.Item.GetItem("Ecommerce").GetItem("MiniCart").GetList("OrderlinesView") != null ? Model.Area.Item.GetItem("Ecommerce").GetItem("MiniCart").GetList("OrderlinesView").SelectedValue : "table"; 9629 9630 Block orderLines = new Block 9631 { 9632 Id = "MiniCartOrderLines", 9633 SkipRenderBlocksList = true, 9634 BlocksList = new List<Block> 9635 { 9636 new Block { 9637 Id = "MiniCartOrderLinesList", 9638 SortId = 20, 9639 Template = RenderMiniCartOrderLinesList() 9640 } 9641 } 9642 }; 9643 9644 Block orderlinesScriptTemplates = new Block 9645 { 9646 Id = "OrderlinesScriptTemplates" 9647 }; 9648 9649 if (orderlinesView == "table") 9650 { 9651 orderLines.Template = RenderMiniCartOrderLinesTable(); 9652 orderLines.BlocksList.Add( 9653 new Block 9654 { 9655 Id = "MiniCartOrderlinesTableHeader", 9656 SortId = 10, 9657 Template = RenderMiniCartOrderLinesHeader() 9658 } 9659 ); 9660 9661 orderlinesScriptTemplates.Template = RenderMiniCartScriptsTableTemplates(); 9662 } 9663 else 9664 { 9665 orderLines.Template = RenderMiniCartOrderLinesBlocks(); 9666 orderlinesScriptTemplates.Template = RenderMiniCartScriptsListTemplates(); 9667 } 9668 9669 miniCartBlocksPage.Add("MasterBottomSnippets", orderlinesScriptTemplates); 9670 9671 Block miniCartScriptTemplates = new Block() 9672 { 9673 Id = "MasterMiniCartTemplates", 9674 SortId = 1, 9675 Template = RenderMiniCartScriptTemplates(), 9676 SkipRenderBlocksList = true, 9677 BlocksList = new List<Block> 9678 { 9679 orderLines, 9680 new Block { 9681 Id = "MiniCartFooter", 9682 Template = RenderMiniCartFooter(), 9683 SortId = 50, 9684 SkipRenderBlocksList = true, 9685 BlocksList = new List<Block> 9686 { 9687 new Block { 9688 Id = "MiniCartSubTotal", 9689 Template = RenderMiniCartSubTotal(), 9690 SortId = 30 9691 }, 9692 new Block { 9693 Id = "MiniCartFees", 9694 Template = RenderMiniCartFees(), 9695 SortId = 40 9696 }, 9697 new Block { 9698 Id = "MiniCartPoints", 9699 Template = RenderMiniCartPoints(), 9700 SortId = 50 9701 }, 9702 new Block { 9703 Id = "MiniCartTotal", 9704 Template = RenderMiniCartTotal(), 9705 SortId = 60 9706 }, 9707 new Block { 9708 Id = "MiniCartDisclaimer", 9709 Template = RenderMiniCartDisclaimer(), 9710 SortId = 70 9711 }, 9712 new Block { 9713 Id = "MiniCartActions", 9714 Template = RenderMiniCartActions(), 9715 SortId = 80 9716 } 9717 } 9718 } 9719 } 9720 }; 9721 9722 miniCartBlocksPage.Add("MasterBottomSnippets", miniCartScriptTemplates); 9723 } 9724 9725 @helper RenderMiniCartScriptsTableTemplates() 9726 { 9727 <script id="MiniCartOrderline" type="text/x-template"> 9728 {{#unless isEmpty}} 9729 <tr> 9730 <td class="u-w60px"><a href="{{link}}" class="{{hideimage}}"><img src="/Admin/Public/GetImage.ashx?width=50&height=50&crop=5&Compression=75&image={{image}}" alt="{{name}}" title="{{name}}"></a></td> 9731 <td class="u-va-middle"> 9732 {{#if note}} 9733 <span class="mini-cart-note">{{note}}</span> 9734 {{/if}} 9735 <a href="{{link}}" class="mini-cart-orderline__name" title="{{name}}">{{name}}</a> 9736 {{#if variantname}} 9737 <a href="{{link}}" class="mini-cart-orderline__name mini-cart-orderline__name--sm">{{variantname}}</a> 9738 {{/if}} 9739 {{#if unitname}} 9740 <div class="mini-cart-orderline__name mini-cart-orderline__name--sm">{{unitname}}</div> 9741 {{/if}} 9742 </td> 9743 <td class="u-ta-right u-va-middle">{{quantity}}</td> 9744 <td class="u-ta-right u-va-middle"> 9745 {{#if pointsTotal}} 9746 <span class="u-color--loyalty-points">{{pointsTotal}}</span> @Translate("points") 9747 {{else}} 9748 {{totalprice}} 9749 {{/if}} 9750 </td> 9751 </tr> 9752 {{/unless}} 9753 </script> 9754 9755 <script id="MiniCartOrderlineDiscount" type="text/x-template"> 9756 {{#unless isEmpty}} 9757 <tr class="table__row--no-border"> 9758 <td class="u-w60px"> 9759 {{#if image}} 9760 @Render(new Image { Path = "{{image}}", Title = "{{name}} {{variantname}}", ImageDefault = new ImageSettings { Width = 60, Height = 60, Crop = 5 }, CssClass = "u-middle-horizontal" }) 9761 {{/if}} 9762 </td> 9763 <td><div class="mini-cart-orderline__name dw-mod">{{name}}</div></td> 9764 <td class="u-ta-right">&nbsp;</td> 9765 <td class="u-ta-right">{{totalprice}}</td> 9766 </tr> 9767 {{/unless}} 9768 </script> 9769 9770 <script id="MiniPmxCartOrderline" type="text/x-template"> 9771 {{#unless isEmpty}} 9772 <tr class="table__row--no-border"> 9773 <td class="u-w60px"> 9774 @Render(new Image { Path = "/Admin/Public/GetImage.ashx?Width=115&Height=115&Crop=5&DoNotUpscale=True&FillCanvas=False&Image=/Files/Images/philipsonwine/pickandmix/Kasse.png", Title = Translate("Smartpage:Checkout.PMXCart.Name", "Din egen vinkasse"), DisableImageEngine = true, CssClass = "product-image" }) 9775 </td> 9776 <td class="u-va-middle"> 9777 <span class="mini-cart-orderline__name">@Translate("Smartpage:Checkout.PMXCart.Name", "Din egen vinkasse") {{nr}}</span> 9778 <div class="mini-cart-orderline__name mini-cart-orderline__name--sm">@Translate("Smartpage:Checkout.PMXCart.TopText", "Pick and mix")</div> 9779 </td> 9780 <td class="u-ta-right u-va-middle">{{quantity}}</td> 9781 <td class="u-ta-right u-va-middle"> 9782 {{totalPriceClean}} 9783 </td> 9784 </tr> 9785 {{/unless}} 9786 </script> 9787 } 9788 9789 @helper RenderMiniCartScriptsListTemplates() 9790 { 9791 int cartFeedPageId = GetPageIdByNavigationTag("MiniCartFeed"); 9792 9793 <script id="MiniCartOrderline" type="text/x-template"> 9794 {{#unless isEmpty}} 9795 <div class="mini-cart-orderline grid dw-mod"> 9796 <div class="grid__col-4"> 9797 <a href="{{link}}" class="{{hideimage}}"> 9798 @{ 9799 string imageEngine = "/Admin/Public/GetImage.ashx?width=100&height=100&crop=5&Compression=75&image={{image}}"; 9800 9801 // CDN 9802 var cdnUrl = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetString("CDNUrl"); 9803 bool cdnActivate = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetBoolean("CDNActivate"); 9804 if (!string.IsNullOrWhiteSpace(cdnUrl) && cdnActivate) 9805 { 9806 imageEngine = cdnUrl + imageEngine; 9807 } 9808 } 9809 <img class="b-lazy" src="/Files/Images/placeholder.gif" data-src="@imageEngine" alt="{{name}}" title="{{name}}"> 9810 </a> 9811 </div> 9812 <div class="grid__col-8"> 9813 <a href="{{link}}" class="mini-cart-orderline__name mini-cart-orderline__name--truncate mini-cart-orderline__name--md u-padding-right--lg" title="{{name}}">{{name}}</a> 9814 {{#if variantname}} 9815 <div class="mini-cart-orderline__name mini-cart-orderline__name--sm dw-mod">@Translate("Variant"): {{variantname}}</div> 9816 {{/if}} 9817 {{#if unitname}} 9818 <div class="mini-cart-orderline__name mini-cart-orderline__name--sm dw-mod">@Translate("Unit"): {{unitname}}</div> 9819 {{/if}} 9820 <div class="mini-cart-orderline__name mini-cart-orderline__name--sm dw-mod">@Translate("Qty"): {{quantity}}</div> 9821 9822 <div class="grid__cell-footer"> 9823 <div class="grid__cell"> 9824 <div class="u-pull--left mini-cart-orderline__price dw-mod"> 9825 {{#if pointsTotal}} 9826 <span class="u-color--loyalty-points">{{pointsTotal}}</span> @Translate("points") 9827 {{else}} 9828 {{totalprice}} 9829 {{/if}} 9830 </div> 9831 <button type="button" 9832 title="@Translate("Remove orderline")" 9833 class="btn btn--clean btn--condensed u-pull--right mini-cart-orderline__remove-btn dw-mod" 9834 onclick="{{#if googleImpression}}googleImpressionRemoveFromCart({{googleImpression}});{{/if}}Cart.UpdateCart('miniCartContent', '/Default.aspx?ID=@cartFeedPageId', 'CartCmd=DelOrderLine&key={{id}}&redirect=false', true);"> 9835 @Translate("Remove") 9836 </button> 9837 </div> 9838 </div> 9839 </div> 9840 </div> 9841 {{/unless}} 9842 </script> 9843 9844 <script id="MiniCartOrderlineDiscount" type="text/x-template"> 9845 {{#unless isEmpty}} 9846 <div class="mini-cart-orderline mini-cart-orderline--discount grid dw-mod"> 9847 <div class="grid__col-8"> 9848 <div class="mini-cart-orderline__name mini-cart-orderline__name dw-mod">{{name}}</div> 9849 </div> 9850 <div class="grid__col-4 u-align-right">{{totalprice}}</div> 9851 </div> 9852 {{/unless}} 9853 </script> 9854 } 9855 9856 @helper RenderMiniCartScriptTemplates() 9857 { 9858 List<Block> subBlocks = this.masterPage.GetBlockListById("MasterMiniCartTemplates").OrderBy(item => item.SortId).ToList(); 9859 bool useGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("GoogleTagManagerID")); 9860 string cartPageLink = string.Concat("/Default.aspx?ID=", GetPageIdByNavigationTag("CartPage")); 9861 bool miniCartUseGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("GoogleTagManagerID")); 9862 9863 <script id="MiniCartContent" type="text/x-template"> 9864 {{#.}} 9865 {{#unless isEmpty}} 9866 @if (miniCartUseGoogleTagManager) 9867 { 9868 <text>{{{googleEnchantImpressionEmptyCart OrderLines}}}</text> 9869 } 9870 @RenderBlockList(subBlocks) 9871 {{/unless}} 9872 {{/.}} 9873 </script> 9874 } 9875 9876 @helper RenderMiniCartOrderLinesTable() 9877 { 9878 List<Block> subBlocks = this.masterPage.GetBlockListById("MiniCartOrderLines").OrderBy(item => item.SortId).ToList(); 9879 9880 <div class="u-overflow-auto"> 9881 <table class="table mini-cart-table dw-mod"> 9882 @RenderBlockList(subBlocks) 9883 </table> 9884 </div> 9885 } 9886 9887 @helper RenderMiniCartOrderLinesBlocks() 9888 { 9889 List<Block> subBlocks = this.masterPage.GetBlockListById("MiniCartOrderLines").OrderBy(item => item.SortId).ToList(); 9890 9891 <div class="u-overflow-auto"> 9892 @RenderBlockList(subBlocks) 9893 </div> 9894 } 9895 9896 @helper RenderMiniCartOrderLinesHeader() 9897 { 9898 <thead> 9899 <tr> 9900 <td>&nbsp;</td> 9901 <td>@Translate("Product")</td> 9902 <td class="u-ta-right">@Translate("Qty")</td> 9903 <td class="u-ta-right" width="150">@Translate("Price")</td> 9904 </tr> 9905 </thead> 9906 } 9907 9908 @helper RenderMiniCartOrderLinesList() 9909 { 9910 <text> 9911 {{#OrderLines}} 9912 {{#ifCond template "===" "CartOrderline"}} 9913 {{>MiniCartOrderline}} 9914 {{/ifCond}} 9915 {{#ifCond template "===" "CartOrderlineMobile"}} 9916 {{>MiniCartOrderline}} 9917 {{/ifCond}} 9918 {{#ifCond template "===" "CartOrderlineDiscount"}} 9919 {{>MiniCartOrderlineDiscount}} 9920 {{/ifCond}} 9921 {{/OrderLines}} 9922 {{#PickAndMixOrderLines}} 9923 {{>MiniPmxCartOrderline}} 9924 {{/PickAndMixOrderLines}} 9925 </text> 9926 } 9927 9928 @helper RenderMiniCartFees() 9929 { 9930 bool pointShop = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 9931 if (!pointShop) 9932 { 9933 <text> 9934 {{#unless hidePaymentfee}} 9935 <div class="grid"> 9936 <div class="grid__col-6 grid__col--bleed-y"> 9937 {{paymentmethod}} 9938 </div> 9939 <div class="grid__col-6 grid__col--bleed-y grid--align-end">{{paymentfee}}</div> 9940 </div> 9941 {{/unless}} 9942 </text> 9943 } 9944 <text> 9945 {{#unless hideShippingfee}} 9946 {{#if shippingmethod}} 9947 <div class="grid"> 9948 <div class="grid__col-6 grid__col--bleed-y"> 9949 {{shippingmethod}} 9950 </div> 9951 <div class="grid__col-6 grid__col--bleed-y grid--align-end">{{shippingfee}}</div> 9952 </div> 9953 {{/if}} 9954 {{/unless}} 9955 </text> 9956 <text> 9957 {{#if hasTaxSettings}} 9958 <div class="grid"> 9959 <div class="grid__col-6 grid__col--bleed-y">@Translate("Sales Tax")</div> 9960 <div class="grid__col-6 grid__col--bleed-y grid--align-end">{{totaltaxes}}</div> 9961 </div> 9962 {{/if}} 9963 </text> 9964 <text> 9965 {{#customerStockOrderlines}} 9966 <div class="grid"> 9967 <div class="grid__col-6 grid__col--bleed-y"> 9968 {{Description}} 9969 </div> 9970 <div class="grid__col-6 grid__col--bleed-y grid--align-end">{{Fee}}</div> 9971 </div> 9972 {{/customerStockOrderlines}} 9973 </text> 9974 } 9975 9976 @helper RenderMiniCartFooter() 9977 { 9978 List<Block> subBlocks = this.masterPage.GetBlockListById("MiniCartFooter").OrderBy(item => item.SortId).ToList(); 9979 9980 <div class="mini-cart__footer u-border-top u-padding-top dw-mod"> 9981 @RenderBlockList(subBlocks) 9982 </div> 9983 } 9984 9985 @helper RenderMiniCartActions() 9986 { 9987 int cartPageId = GetPageIdByNavigationTag("CartPage"); 9988 9989 <button type="button" title="@Translate("Empty cart")" class="btn btn--secondary u-full-width dw-mod u-no-margin u-margin-bottom" onclick="googleEnchantImpressionEmptyCart(); Cart.EmptyCart(event);">@Translate("Empty cart")</button> 9990 <a href="/Default.aspx?ID=@cartPageId" title="@Translate("Proceed to checkout")" class="btn btn--primary u-full-width u-no-margin dw-mod">@Translate("Proceed to checkout")</a> 9991 } 9992 9993 @helper RenderMiniCartPoints() 9994 { 9995 <text> 9996 {{#if earnings}} 9997 <div class="grid"> 9998 <div class="grid__col-6 grid__col--bleed-y">@Translate("Earnings")</div> 9999 <div class="grid__col-6 grid__col--bleed-y grid--align-end"> 10000 <div> 10001 <span class="u-color--loyalty-points">{{earnings}}</span> @Translate("points") 10002 </div> 10003 </div> 10004 </div> 10005 {{/if}} 10006 </text> 10007 } 10008 10009 @helper RenderMiniCartSubTotal() 10010 { 10011 bool hasTaxSettings = Dynamicweb.Rapido.Services.Countries.HasTaxSettings(Model.Cart.ID); 10012 bool pointShop = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 10013 if (!pointShop) 10014 { 10015 <text> 10016 {{#unless hideSubTotal}} 10017 <div class="grid dw-mod u-bold"> 10018 <div class="grid__col-6 grid__col--bleed-y">@Translate("Subtotal")</div> 10019 <div class="grid__col-6 grid__col--bleed-y grid--align-end"> 10020 @if (hasTaxSettings) 10021 { 10022 <text>{{subtotalpricewithouttaxes}}</text> 10023 } 10024 else 10025 { 10026 <text>{{subtotalprice}}</text> 10027 } 10028 </div> 10029 </div> 10030 {{/unless}} 10031 </text> 10032 } 10033 } 10034 10035 @helper RenderMiniCartTotal() 10036 { 10037 bool pointShop = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 10038 10039 <div class="mini-cart-totals grid u-border-top u-margin-top dw-mod"> 10040 <div class="grid__col-6">@Translate("Total")</div> 10041 <div class="grid__col-6 grid--align-end"> 10042 <div> 10043 @if (pointShop) 10044 { 10045 <span class="u-color--loyalty-points">{{pointsUsedInCart}}</span> @Translate("points") 10046 } 10047 else 10048 { 10049 <text>{{totalprice}}</text> 10050 } 10051 </div> 10052 </div> 10053 </div> 10054 } 10055 10056 @helper RenderMiniCartDisclaimer() 10057 { 10058 <text> 10059 {{#if showCheckoutDisclaimer}} 10060 <div class="grid u-margin-bottom u-ta-right"> 10061 <small class="grid__col-12">{{checkoutDisclaimer}}</small> 10062 </div> 10063 {{/if}} 10064 </text> 10065 } 10066 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 10067 @using Dynamicweb.Rapido.Blocks 10068 @using Dynamicweb.Rapido.Blocks.Components.General 10069 @using Custom.StockHandler.Models.ViewModels 10070 @using Smartpage.Relewise.Services.Models 10071 10072 @using Dynamicweb.Ecommerce.ProductCatalog 10073 @using Dynamicweb.Rendering 10074 @using Dynamicweb.Core 10075 @using System 10076 @using System.Web 10077 @using System.Collections.Generic 10078 @using Dynamicweb.Rapido.Blocks 10079 @using Dynamicweb.Rapido.Blocks.Components 10080 @using Dynamicweb.Rapido.Blocks.Components.General 10081 @using Dynamicweb.Rapido.Services 10082 @using Smartpage.PhilipsonWine.PickNMix.Helper; 10083 10084 @helper GridView(Dynamicweb.Frontend.ItemViewModel gridViewSettings) 10085 { 10086 string imageZoomOnHover = gridViewSettings.GetBoolean("HoverImageZoom") ? "image-hover--zoom" : ""; 10087 <script id="ProductGridItemContainer" type="text/x-template"> 10088 {{#.}} 10089 {{#unless ispickMixProductContainer}} 10090 <div id="Product{{id}}" data-template="GridViewItem" data-preloader="overlay" class="product-list__grid-item @imageZoomOnHover dw-mod product-list-product js-product-list-product {{bannerIsActiveClass}}" style="{{#Banner}}{{bannerStyle}}{{/Banner}}"> 10091 {{#Product}} 10092 {{>GridViewItem}} 10093 {{/Product}} 10094 {{#Banner}} 10095 {{>GridViewItemBanner}} 10096 {{/Banner}} 10097 </div> 10098 {{/unless}} 10099 {{/.}} 10100 </script> 10101 10102 <script id="ProductListSchema" type="text/x-template"> 10103 { 10104 "@@context": "https://schema.org", 10105 "@@type": "ItemList", 10106 "@@id": "{{schemaId}}", 10107 "name": "{{schemaName}}", 10108 "url": "{{schemaUrl}}", 10109 "description": "{{schemaDescription}}", 10110 "numberOfItems" : {{currentProducts}}, 10111 "itemListElement": [ 10112 {{#ProductsContainer}} 10113 {{#Product}} 10114 { 10115 "@@type": "ListItem", 10116 "position": {{schemaPosition}}, 10117 "item": { 10118 "@@type": "Product", 10119 "name": "{{name}}", 10120 "description": "{{description}}", 10121 "image": "{{image}}", 10122 "offers": { 10123 "@@type": "{{schemaOfferType}}", 10124 {{#ifCond schemaOfferType '===' "AggregateOffer"}} 10125 "lowPrice": {{schemaVolumePrice}}, 10126 "highPrice": {{schemaUnitPrice}}, 10127 {{/ifCond}} 10128 {{#ifCond schemaOfferType '===' "Offer"}} 10129 "price": {{schemaUnitPrice}}, 10130 {{/ifCond}} 10131 "priceCurrency": "{{currency}}", 10132 "itemCondition": "https://schema.org/NewCondition" 10133 }, 10134 "url": "{{schemaUrlFull}}" 10135 } 10136 }, 10137 {{/Product}} 10138 {{/ProductsContainer}} 10139 ] 10140 } 10141 </script> 10142 } 10143 10144 @helper RenderGridViewItemBanner() 10145 { 10146 <script id="GridViewItemBanner" type="text/x-template"> 10147 <div class="grid__col--auto product-scroll-trigger u-no-padding u-full-height u-grey-border u-white-background @(Pageview.Device.ToString() == "Desktop" ? "u-padding-sides-8px" : "") banner-grid {{textPlacement}}" style="background: url('{{bannerImage}}');"> 10148 <div class="grid__col-12 u-padding-sides-8px banner-text-padding"> 10149 {{#if bannerTeaserText}} 10150 <div> 10151 <p style="color: {{bannerTextColor}}" class="banner-teaser-text u-padding-sides-8px">{{{bannerTeaserText}}}</p> 10152 </div> 10153 {{/if}} 10154 {{#if bannerText}} 10155 <div> 10156 <p style="color: {{bannerTextColor}}" class="banner-text u-padding-sides-8px">{{{bannerText}}}</p> 10157 </div> 10158 {{/if}} 10159 {{#if showDivider}} 10160 <hr class="banner-divider-line" /> 10161 {{/if}} 10162 {{#if uspItems}} 10163 <div class="banner-usp-container"> 10164 {{#each uspItems}} 10165 <div class="banner-usp"> 10166 {{#if this.Icon}} 10167 <img class="banner-usp-icon" src="{{this.Icon}}" /> 10168 {{/if}} 10169 {{#if this.Label}} 10170 <p class="banner-usp-label">{{this.Label}}</p> 10171 {{/if}} 10172 </div> 10173 {{/each}} 10174 </div> 10175 {{/if}} 10176 {{#if showButton}} 10177 <div class="grid__col-8 btn-banner-wrapper"> 10178 <a class="btn btn-banner u-padding-sides-8px" href="{{bannerButtonLink}}">{{bannerButtonText}}</a> 10179 </div> 10180 {{/if}} 10181 </div> 10182 </div> 10183 </script> 10184 } 10185 10186 @helper RenderGridViewItem(BlocksPage page) 10187 { 10188 List<Block> subBlocks = page.GetBlockListById("GridViewItem"); 10189 int sliderSpeed = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetInt32("IconSliderSpeed") != 0 ? Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetInt32("IconSliderSpeed") : 3000; 10190 10191 <script id="GridViewItem" type="text/x-template"> 10192 {{#.}} 10193 <div class="grid-card{{#if useCustomCocktailProductCardDesign}} cocktail-product-grid-card{{else}}{{#if isProductList}} u-white-background{{/if}}{{/if}}{{#if TastingNotes}} hover-extend-height{{/if}}"> 10194 <div class="grid__col--auto js-product-scroll-trigger product-scroll-trigger u-no-padding u-full-height{{#if useCustomCocktailProductCardDesign}} cocktail-pack-product{{else}}{{#if isProductList}} grid-card-container{{else}} u-white-background{{/if}}{{/if}}" data-params="{{googleImpression}}"> 10195 {{#unless isProductList}} 10196 {{#unless RecommendationDisplayAsGrid}} 10197 {{>RenderBadges}} 10198 {{>RenderLabels}} 10199 {{/unless}} 10200 {{/unless}} 10201 @RenderBlockList(subBlocks) 10202 10203 {{#unless RecommendationDisplayAsGrid}} 10204 <div class="grid-footer touch-device-prices-container prices-container u-full-width"> 10205 @RenderGridViewAddToCartSection() 10206 </div> 10207 {{/unless}} 10208 </div> 10209 10210 {{#if RecommendationActivatePodium}} 10211 {{#if RecommendationDisplayAsGrid}} 10212 <span class="recommendation-podium-rank {{RecommendationPodiumRankClasses}}" style="{{RecommendationPodiumRankSize}}{{RecommendationPodiumRankGradientColor}}">{{RecommendationPodiumRank}}</span> 10213 {{/if}} 10214 {{/if}} 10215 </div> 10216 {{/.}} 10217 </script> 10218 10219 <script id="RenderBadges" type="text/x-template"> 10220 <div class="productlist-badges"> 10221 @RenderGridViewItemStickers() 10222 {{#ExpertRatings}} 10223 {{#if isFreeText}} 10224 <div class="rating-badge c100"> 10225 <span class="rating-badge--score__freetext">{{text}}</span> 10226 </div> 10227 {{else}} 10228 {{#if isInterval}} 10229 <div class="rating-badge c100"> 10230 <span class="rating-badge--score__interval">{{{text}}}</span> 10231 <span class="rating-badge--text">{{name}}</span> 10232 </div> 10233 {{else}} 10234 <div class="rating-badge c100"> 10235 <span class="rating-badge--score">{{{text}}}</span> 10236 <span class="rating-badge--text">{{name}}</span> 10237 </div> 10238 {{/if}} 10239 {{/if}} 10240 {{/ExpertRatings}} 10241 </div> 10242 </script> 10243 10244 <script id="RenderLabels" type="text/x-template"> 10245 @RenderLabels() 10246 </script> 10247 } 10248 10249 @helper RenderLabels() 10250 { 10251 <div class="label-container{{#if ProductRibbons}} js-horizontal-auto-scroll-container{{/if}}"> 10252 {{#if bomQuantity}} 10253 <div class="top-label"> 10254 <span class="top-label__bom-quantity">{{{bomQuantity}}}</span> 10255 </div> 10256 {{/if}} 10257 {{#ProductRibbons}} 10258 <div class="top-label"> 10259 <div class="top-label__label top-label__label" style="background-color:{{RibbonBgColor}}; color:{{RibbonTextColor}};"> 10260 {{#if RibbonCustomRank}} 10261 <div class="custom-label-icon">{{RibbonCustomRank}}</div> 10262 {{/if}} 10263 {{RibbonText}} 10264 {{#if TooltipText}} 10265 <i class="fal fa-question-circle info-icon js-tooltip tooltip-icon tooltip-icon--product-list" data-tooltip-placement="{{TooltipPlacement}}" data-tooltip-content="{{TooltipText}}"></i> 10266 {{/if}} 10267 </div> 10268 </div> 10269 {{/ProductRibbons}} 10270 </div> 10271 } 10272 10273 @helper RenderGridViewItemHiddenProperties() 10274 { 10275 <input type="hidden" name="ProductLoopCounter{{id}}" value="{{id}}" /> 10276 @*<input type="hidden" name="ProductID{{id}}" value="{{productId}}" />*@ 10277 <input type="hidden" name="VariantID{{id}}" value="{{variantid}}" id="Variant_{{id}}" /> 10278 <input type="hidden" name="UnitID{{id}}" value="{{unitId}}" id="Unit_{{id}}" /> 10279 } 10280 10281 @helper RenderGridViewItemImageContainer(BlocksPage page) 10282 { 10283 List<Block> subBlocks = page.GetBlockListById("GridViewItemImageContainer"); 10284 10285 <div class="product-list__grid-item__image dw-mod {{#if isBomParent}}bom-parent-image-container{{/if}} {{#if RecommendationProductCardBackgroundColor}}u-transparent-background{{/if}} {{noImage}} {{#if RecommendationActivatePodium}}{{#unless RecommendationDisplayAsGrid}}u-position-relative{{/unless}}{{/if}}"> 10286 @RenderBlockList(subBlocks) 10287 </div> 10288 } 10289 10290 @helper RenderGridViewItemImage() 10291 { 10292 <text> 10293 {{#if isPickAndMixPage}} 10294 <div class="grid-image-container pmx-grid-image-container"> 10295 <div class="grid-image pmx-modal-trigger js-pmx-modal-trigger" style="background-image: url('{{image}}');" data-product-id="{{productId}}"></div> 10296 </div> 10297 {{else}} 10298 <a href="{{link}}" 10299 onclick="Scroll.SavePosition(event); {{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" 10300 class="u-block u-position-relative image-hover__wrapper dw-mod"> 10301 <div class="grid-image-container{{#if eventProduct}} event-grid-image-container{{/if}}{{#if useCustomCocktailProductCardDesign}} cocktail-grid-image-container{{/if}}" style="{{RecommendationProductCardGradientStyle}}"> 10302 <div class="grid-image{{#if isBomParent}} bom-parent-image{{/if}}" style="background-image: url('{{image}}');" alt="{{name}}"></div> 10303 </div> 10304 </a> 10305 {{#if RecommendationActivatePodium}} 10306 {{#unless RecommendationDisplayAsGrid}} 10307 <span class="recommendation-podium-rank {{RecommendationPodiumRankClasses}}" style="{{RecommendationPodiumRankSize}}{{RecommendationPodiumRankGradientColor}}">{{RecommendationPodiumRank}}</span> 10308 {{/unless}} 10309 {{/if}} 10310 {{/if}} 10311 </text> 10312 10313 } 10314 10315 @helper RenderGridViewItemStickers() 10316 { 10317 <text> 10318 {{#StickersContainers}} 10319 {{>StickersContainer}} 10320 {{/StickersContainers}} 10321 </text> 10322 } 10323 10324 @helper RenderGridViewItemFavorites() 10325 { 10326 <div class="favorites favorites--for-grid-view u-pull--right {{favoriteProductFromImport}} dw-mod" {{favoriteProductFromImport}}> 10327 {{#Favorite}} 10328 {{>FavoriteTemplate}} 10329 {{/Favorite}} 10330 </div> 10331 } 10332 10333 @helper RenderGridViewItemInfoContainer(BlocksPage page) 10334 { 10335 List<Block> subBlocks = page.GetBlockListById("GridViewItemInfoContainer"); 10336 10337 <div class="grid__cell product-list__grid-item__price-info dw-mod"> 10338 @RenderBlockList(subBlocks) 10339 </div> 10340 } 10341 10342 @helper RenderGridViewItemTitle() 10343 { 10344 <a href="{{link}}" class="u-color-inherit" onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}"> 10345 <h6 class="u-condensed-text u-bold">{{{name}}}{{#if variantName}}, {{variantName}}{{/if}}</h6> 10346 </a> 10347 } 10348 10349 @helper RenderGridViewItemNumber() 10350 { 10351 <div class="item-number dw-mod">{{number}}</div> 10352 } 10353 10354 @helper RenderGridViewItemPrice(Dynamicweb.Frontend.ItemViewModel gridViewSettings) 10355 { 10356 int columnsCount = gridViewSettings.GetList("Columns") != null ? Converter.ToInt32(gridViewSettings.GetList("Columns").SelectedValue) : 4; 10357 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 10358 bool showCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton"); 10359 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("ShowBothPricesWithWithoutVAT"); 10360 bool isPricesWithVATEnabled = Converter.ToBoolean(Pageview.Area.EcomPricesWithVat); 10361 10362 if (pointShopOnly) 10363 { 10364 <text> 10365 {{#if havePointPrice}} 10366 <div class="price price--product-list dw-mod">{{points}} @Translate("points")</div> 10367 @if (showCartButton) 10368 { 10369 <text> 10370 {{#unless canBePurchasedWithPoints}} 10371 <small class="help-text u-no-margin">@Translate("Not enough points to buy this")</small> 10372 {{/unless}} 10373 </text> 10374 } 10375 {{else}} 10376 @Translate("Not available") 10377 {{/if}} 10378 </text> 10379 10380 } 10381 else 10382 { 10383 <div class="price price--product-list dw-mod">{{price}}</div> 10384 <div class="before-price {{onSale}} dw-mod">{{discount}}</div> 10385 if (showVATPrice) 10386 { 10387 <div class="vat-price vat-price--product-list u-margin-top dw-mod"> 10388 @if (columnsCount <= 4) 10389 { 10390 if (isPricesWithVATEnabled) 10391 { 10392 <span>@Translate("excl. VAT")</span><span> ({{priceWithoutVAT}})</span> 10393 } 10394 else 10395 { 10396 <span>@Translate("incl. VAT")</span><span> ({{priceWithVAT}})</span> 10397 } 10398 } 10399 else 10400 { 10401 if (isPricesWithVATEnabled) 10402 { 10403 <div>@Translate("excl. VAT")</div><div>({{priceWithoutVAT}})</div> 10404 } 10405 else 10406 { 10407 <div>@Translate("incl. VAT")</div><div>({{priceWithVAT}})</div> 10408 } 10409 } 10410 </div> 10411 } 10412 <text> 10413 {{#if priceRRP}} 10414 <div><small>@Translate("RRP") {{priceRRP}}</small></div> 10415 {{/if}} 10416 </text> 10417 } 10418 } 10419 10420 @helper RenderGridViewItemFooter(BlocksPage page, Dynamicweb.Frontend.ItemViewModel gridViewSettings) 10421 { 10422 List<Block> subBlocks = page.GetBlockListById("GridViewItemFooter"); 10423 bool showStaticVariants = gridViewSettings.GetBoolean("ShowStaticVariants"); 10424 string footerClasses = showStaticVariants ? "u-min-h120px" : ""; 10425 10426 <div class="grid-footer{{#if isBomParent}} bom-parent-grid-footer{{/if}}"> 10427 {{#if isProductList}} 10428 {{#unless RecommendationDisplayAsGrid}} 10429 {{>RenderBadges}} 10430 {{>RenderLabels}} 10431 {{/unless}} 10432 {{/if}} 10433 <div class="{{#if isProductList}}grid-footer-flex{{else}}product-list__grid-item__footer dw-mod u-padding-1px{{/if}} @footerClasses {{#if RecommendationDisplayAsGrid}}{{#if RecommendationProductCardBackgroundColor}}u-transparent-background{{/if}}{{/if}}"> 10434 @RenderBlockList(subBlocks) 10435 </div> 10436 {{#if RecommendationDisplayAsGrid}} 10437 <div class="grid-footer touch-device-prices-container prices-container u-full-width"> 10438 @RenderGridViewAddToCartSection() 10439 </div> 10440 {{/if}} 10441 </div> 10442 } 10443 10444 @helper RenderGridViewItemViewButton(Dynamicweb.Frontend.ItemViewModel gridViewSettings) 10445 { 10446 string viewMoreText = gridViewSettings.GetString("ViewMoreText"); 10447 viewMoreText = !string.IsNullOrEmpty(viewMoreText) ? viewMoreText : "View"; 10448 10449 @Render(new Link 10450 { 10451 Href = "{{link}}", 10452 Id = "CartButton_{{id}}", 10453 Title = Translate(viewMoreText), 10454 OnClick = "{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}", 10455 ButtonLayout = ButtonLayout.Secondary, 10456 CssClass = "u-no-margin" 10457 }); 10458 } 10459 10460 @helper RenderGridViewItemPricesAndAddToCart(Dynamicweb.Frontend.ItemViewModel gridViewSettings) 10461 { 10462 int columnsCount = gridViewSettings.GetList("Columns") != null ? Converter.ToInt32(gridViewSettings.GetList("Columns").SelectedValue) : 4; 10463 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 10464 bool showCartButton = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView").GetBoolean("ShowAddToCartButton"); 10465 bool showVATPrice = Pageview.AreaSettings.GetItem("ProductList").GetBoolean("ShowBothPricesWithWithoutVAT"); 10466 bool isPricesWithVATEnabled = Converter.ToBoolean(Pageview.Area.EcomPricesWithVat); 10467 10468 <text> 10469 {{#if isProductList}} 10470 <div> 10471 <div class="grid__col-12 {{#if eventProduct}}event-{{/if}}{{#if useCustomCocktailProductCardDesign}}cocktail-title-container {{/if}}title-container"> 10472 {{#unless eventProduct}} 10473 {{#unless cocktailProduct}} 10474 {{#unless RecommendationDisplayAsGrid}} 10475 {{#if producerName}} 10476 <span class="area">{{producerName}}</span> 10477 {{/if}} 10478 {{/unless}} 10479 {{/unless}} 10480 {{/unless}} 10481 {{#if isPickAndMixPage}} 10482 <h3 class="title js-title pmx-modal-trigger js-pmx-modal-trigger" data-product-id="{{productId}}">{{name}}</h3> 10483 {{else}} 10484 <a href="{{link}}" class="u-color-inherit" onclick="Scroll.SavePosition(event); {{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}"> 10485 <h3 class="title js-title {{#if useCustomCocktailProductCardDesign}}cocktail-product-title u-ta-left{{/if}}">{{name}}</h3> 10486 </a> 10487 {{#if useCustomCocktailProductCardDesign}} 10488 <span class="cocktail-product-name-divider"></span> 10489 {{/if}} 10490 {{/if}} 10491 {{#if eventProduct}} 10492 <p class="event-place"> 10493 {{eventRestaurantName}}, {{eventAddressShort}} 10494 <span class="event-time">{{eventDate}}, {{eventTime}}</span> 10495 </p> 10496 {{/if}} 10497 {{#unless eventProduct}} 10498 {{#unless RecommendationDisplayAsGrid}} 10499 <div class="{{#if useCustomCocktailProductCardDesign}} u-padding-left-none u-padding-right-none{{else}} u-padding-top{{/if}}"> 10500 {{#if useCustomCocktailProductCardDesign}} 10501 <div class="cocktail-product-short-description"> 10502 {{{productDescription}}} 10503 </div> 10504 {{else}} 10505 <div class="tags"> 10506 {{#if country}} 10507 {{#ifCond area "||" type}} 10508 <span class="tags__tag"> 10509 {{#if flagIconClass}} 10510 <span class="flag-icon {{flagIconClass}}"></span> 10511 {{/if}} 10512 {{country}} 10513 </span> 10514 <span class="tags__divider-dot"></span> 10515 {{else}} 10516 <span class="tags__tag"> 10517 {{#if flagIconClass}} 10518 <span class="flag-icon {{flagIconClass}}"></span> 10519 {{/if}} 10520 {{country}} 10521 </span> 10522 {{/ifCond}} 10523 {{/if}} 10524 {{#if area}} 10525 {{#if type}} 10526 <span class="tags__tag">{{area}}</span> 10527 <span class="tags__divider-dot"></span> 10528 {{else}} 10529 <span class="tags__tag">{{area}}</span> 10530 {{/if}} 10531 {{/if}} 10532 {{#if type}} 10533 <span class="tags__tag"> 10534 {{type}} 10535 </span> 10536 {{/if}} 10537 </div> 10538 {{/if}} 10539 </div> 10540 {{/unless}} 10541 {{/unless}} 10542 </div> 10543 </div> 10544 @*If in a product list context*@ 10545 {{#if isProductList}} 10546 <a href="{{link}}" class="u-color-inherit" onclick="Scroll.SavePosition(event); {{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}"> 10547 {{#if ListViewExpertRatings}} 10548 <div class="description-container"> 10549 {{#if ratingQuote}} 10550 <div class="main-expert-rating-quote">{{{ratingQuote}}}</div> 10551 {{else}} 10552 {{#if productDescription}} 10553 <div class="medium-description">{{{productDescription}}}</div> 10554 {{/if}} 10555 {{/if}} 10556 <div class="main-expert-ratings"> 10557 {{#ListViewExpertRatings}} 10558 <div class="main-expert-ratings__li"> 10559 <label class="main-expert-ratings__label">{{ratingMedia}}</label> 10560 <span class="main-expert-ratings__span"> 10561 {{{rating}}} 10562 </span> 10563 </div> 10564 {{/ListViewExpertRatings}} 10565 </div> 10566 {{#if isDesktop}} 10567 @RenderTastingNotes() 10568 {{/if}} 10569 </div> 10570 {{else}} 10571 {{#if productDescription}} 10572 <div class="description-container"> 10573 <div class="medium-description">{{{productDescription}}}</div> 10574 {{#if isDesktop}} 10575 @RenderTastingNotes() 10576 {{/if}} 10577 </div> 10578 {{/if}} 10579 {{/if}} 10580 </a> 10581 {{/if}} 10582 @*If not in a product list context (e.g. Recommendations)*@ 10583 {{else}} 10584 <div class="grid"> 10585 <div class="grid__col-12 {{#if eventProduct}}event-{{/if}}{{#if useCustomCocktailProductCardDesign}}cocktail-title-container {{/if}}title-container"> 10586 {{#unless eventProduct}} 10587 {{#unless cocktailProduct}} 10588 {{#unless RecommendationDisplayAsGrid}} 10589 <span class="area u-ta-center">{{producerName}}</span> 10590 {{/unless}} 10591 {{/unless}} 10592 {{/unless}} 10593 {{#if isPickAndMixPage}} 10594 <h3 class="title js-title u-ta-center pmx-modal-trigger js-pmx-modal-trigger" data-product-id="{{productId}}">{{name}}</h3> 10595 {{else}} 10596 <a href="{{link}}" class="u-color-inherit" onclick="Scroll.SavePosition(event); {{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" title="{{name}}"> 10597 <h3 class="title js-title {{#if useCustomCocktailProductCardDesign}}cocktail-product-title u-ta-left{{else}}u-ta-center{{/if}}">{{name}}</h3> 10598 </a> 10599 {{#if useCustomCocktailProductCardDesign}} 10600 <span class="cocktail-product-name-divider"></span> 10601 {{/if}} 10602 {{/if}} 10603 10604 {{#if eventProduct}} 10605 <p class="event-place"> 10606 {{eventRestaurantName}}, {{eventAddressShort}} 10607 <span class="event-time">{{eventDate}}, {{eventTime}}</span> 10608 </p> 10609 {{/if}} 10610 </div> 10611 </div> 10612 {{#unless eventProduct}} 10613 {{#unless RecommendationDisplayAsGrid}} 10614 <div class="grid"> 10615 <div class="grid__col-12{{#if useCustomCocktailProductCardDesign}} u-padding-left-none u-padding-right-none{{/if}}"> 10616 {{#if useCustomCocktailProductCardDesign}} 10617 <div class="cocktail-product-short-description"> 10618 {{description}} 10619 </div> 10620 {{else}} 10621 <div class="tags"> 10622 {{#if type}} 10623 {{#ifCond area "||" country}} 10624 <span class="tags__tag"> 10625 {{type}}, 10626 </span> 10627 {{else}} 10628 <span class="tags__tag"> 10629 {{type}} 10630 </span> 10631 {{/ifCond}} 10632 {{/if}} 10633 {{#if area}} 10634 {{#if country}} 10635 <span class="tags__tag">{{area}},</span> 10636 {{else}} 10637 <span class="tags__tag">{{area}}</span> 10638 {{/if}} 10639 {{/if}} 10640 {{#if country}} 10641 <span class="tags__tag">{{country}}</span> 10642 {{/if}} 10643 </div> 10644 {{/if}} 10645 </div> 10646 </div> 10647 {{/unless}} 10648 {{/unless}} 10649 {{/if}} 10650 </text> 10651 10652 <text> 10653 {{#if isAddToCartModal}} 10654 <div class="savings">@Translate("Smartpage:ProductList.Product.Save", "SPAR") <strong>{{savings}}</strong> @Translate("Smartpage:ProductList.Product.PerUnit", "PR. FL.")</div> 10655 {{/if}} 10656 10657 @RenderGridViewAddToCartSection(true) 10658 </text> 10659 } 10660 10661 @helper RenderTastingNotes() 10662 { 10663 <text> 10664 {{#if TastingNotes}} 10665 <div class="tasting-notes-section__notes-container productlist-tasting-notes"> 10666 <div class="tasting-notes-title">@Translate("Custom:ProductList.TastingNotes", "Smagsnoter:")</div> 10667 {{#TastingNotes}} 10668 <div class="tasting-notes-section__note"> 10669 <img src="{{ImageFileName}}" alt="{{AromasFlavours}}" onerror="this.style.display='none'; this.onerror=null;" /> 10670 <div class="tasting-notes-section__note__text">{{AromasFlavours}}</div> 10671 </div> 10672 {{/TastingNotes}} 10673 </div> 10674 {{/if}} 10675 </text> 10676 } 10677 10678 @helper RenderGridViewAddToCartSection(bool showOnDesktop = false) 10679 { 10680 string idSuffix = showOnDesktop ? "_desktop" : "_mobile"; 10681 10682 <div class="@(showOnDesktop ? "desktop-prices-container" : "") {{#if isProductList}}u-flex{{else}}grid{{/if}}"> 10683 <div class="{{pricesSectionCol}}{{#if useCustomCocktailProductCardDesign}} u-padding-left-none u-padding-right-none{{/if}}"> 10684 <div class="prices"> 10685 {{#unless eventProduct}} 10686 {{#unless isAddToCartModal}} 10687 {{#if bomItemSavings}} 10688 <div class="savings">@Translate("Smartpage:ProductList.Product.Save", "SPAR") <strong>{{bomItemSavingsFormatted}}</strong></div> 10689 {{else if savings}} 10690 <div class="savings">@Translate("Smartpage:ProductList.Product.Save", "SPAR") <strong>{{savings}}</strong> @Translate("Smartpage:ProductList.Product.PerUnit", "PR. FL.")</div> 10691 {{else}} 10692 {{/if}} 10693 {{/unless}} 10694 {{/unless}} 10695 <div class="price price--product-list dw-mod"> 10696 {{#if isProductList}} 10697 {{priceWithoutSymbol}} 10698 <span class="price--product-list__currency-code">&nbsp;{{currency}}</span> 10699 {{else}} 10700 {{price}} 10701 {{/if}} 10702 {{#if isSubscription}} 10703 @Translate("Smartpage:Checkout.PerMonth", "/md") 10704 {{/if}} 10705 </div> 10706 <div class="quantity-price"> 10707 {{#if isBomParent}} 10708 {{#if bomItemsTotalPriceNotZero}} 10709 <span class="u-block u-color-font-black quantity-price__amount"><strong><s>{{bomQuantityDescription}}</s></strong></span> 10710 {{/if}} 10711 {{pricePerBomItem}} 10712 {{/if}} 10713 {{{quantityDescription}}} 10714 </div> 10715 </div> 10716 </div> 10717 {{#if availableForPurchase}} 10718 {{#unless RecommendationDisplayAsGrid}} 10719 <div class="{{addToCartSectionCol}}{{#if useCustomCocktailProductCardDesign}} u-padding-left-none u-padding-right-none{{/if}} add-to-cart {{#if isDesktop}}u-padding-left-none u-padding-right-none{{/if}}"> 10720 <div> 10721 <div class="grid grid--justify-space-between product-list-validate-product-amount-container js-validate-product-amount-container {{#if isPickAndMixPage }}pmx-add-wrapper{{/if}}"> 10722 {{#unless disabledBuyButton}} 10723 {{#unless isPickAndMixPage}} 10724 {{#unless isSubscription}} 10725 <div class="grid__col-6 u-no-padding product-amount-validation-container-max-content"> 10726 <span class="product-amount-validation-container product-amount-validation-container__product-list"> 10727 <input disabled id="Quantity{{productId}}@idSuffix" name="Quantity{{id}}" min="1" max="{{stockLevel}}" value="" data-kolli="{{highestQuantity}}" {{#if productInCartQuantity}} data-product-in-cart-quantity="{{productInCartQuantity}}" {{/if}} type="number" class="quantity dw-mod js-stockcheck js-change-quantity js-product-amount-validation__input" data-max-order-quantity-rule-active="{{MaxOrderQuantityRuleActive}}"> 10728 <select id="SelectQuantity{{productId}}@idSuffix" name="SelectQuantity{{id}}" min="1" max="{{stockLevel}}" data-max-order-quantity-rule-active="{{MaxOrderQuantityRuleActive}}" class="u-no-padding quantity dw-mod product-amount-validation__select js-product-amount-validation__select"> 10729 {{#each productAmountSelection}} 10730 <option {{#if IsDefault}} selected {{/if}} value="{{Value}}">{{Value}}</option> 10731 {{/each}} 10732 <option value="other">@Translate("Products.Amount.Selector.Other", "Andet")</option> 10733 </select> 10734 </span> 10735 </div> 10736 {{else}} 10737 <input id="Quantity{{id}}@idSuffix" name="Quantity{{id}}" min="1" value="1" type="hidden" class="dw-mod js-stockcheck js-change-quantity" data-max-order-quantity-rule-active="{{MaxOrderQuantityRuleActive}}"> 10738 {{/unless}} 10739 {{/unless}} 10740 {{/unless}} 10741 {{#if disabledBuyButton}} 10742 <div class="grid__col-12 u-no-padding"> 10743 <button class="btn btn--add-to-cart {{disabledBuyButton}}" title="@Translate("Smartpage:Product.Buy.OutOfStock", "Udsolgt")" onclick="Cart.AddToCart(event, { id: '{{productId}}', variantId: '{{variantid}}', unitId: '{{unitId}}', productInfo: {{productInfo}}, quantity: parseInt(document.getElementById('Quantity{{id}}@idSuffix').value), SpPrimeur: '{{isPrimeur}}'}); {{facebookPixelAction}}" type="button"> 10744 <span>@Translate("Smartpage:Product.Buy.OutOfStock", "Udsolgt")</span> 10745 </button> 10746 </div> 10747 {{/if}} 10748 {{#unless disabledBuyButton}} 10749 <div class="invalid-amount-tooltip invalid-amount-tooltip-on-product-list grid__col-6 u-no-padding js-product-amount-validation-btn-container"> 10750 {{#if isPickAndMixPage}} 10751 @{ 10752 string picknmixFeed = $"/Default.aspx?ID={GetPageIdByNavigationTag("picknmixfeedpage")}"; 10753 string pageId = Dynamicweb.Context.Current.Request["ID"]; 10754 10755 string productFeedUrl = $"/Default.aspx?ID={GetPageIdByNavigationTag("picknmix")}"; 10756 10757 productFeedUrl += "&MainProductId={prodIds}&feed=true&redirect=false&pickandmixlist=true"; 10758 } 10759 <div class="u-position-relative js-pmx-add-wrapper"> 10760 <button class="btn btn--add-to-cart add-to-pmx js-add-to-pmx {{#if quantityPickedPmx}} d-none {{/if}}" title="@HttpUtility.HtmlAttributeEncode(Translate("Smartpage:PickAndMix.Product.Buy", "Køb"))" data-currfeedurl="@productFeedUrl" data-id="{{productId}}" data-productname="{{name}}" data-maxquantity="{{stockLevel}}" data-method="add" data-feedurl="@picknmixFeed" type="button" data-currency-code="{{currency}}"> 10761 <span>@Translate("Smartpage:PickAndMix.Product.Buy", "Tilføj")</span> 10762 </button> 10763 <div class="js-pmx-add-remove-wrap pmx-add-remove-wrap {{#unless quantityPickedPmx}} d-none {{/unless}}"> 10764 <div class="action js-remove-from-pmx" data-currfeedurl="@productFeedUrl" data-id="{{productId}}" data-method="delete" data-feedurl="@picknmixFeed" data-currency-code="{{currency}}" data-index="0"> 10765 - 10766 </div> 10767 <input class="js-update-pmx" data-input-id="js-pmx-input{{productId}}" min="0" type="number" value="{{quantityPickedPmx}}" data-id="{{productId}}" data-maxquantity="{{stockLevel}}" data-method="update" data-productname="{{name}}" data-feedurl="@picknmixFeed" data-currency-code="{{currency}}" data-index="0" data-currfeedurl="@productFeedUrl" /> 10768 <div class="action js-add-to-pmx" data-maxquantity="{{stockLevel}}" data-productname="{{name}}" data-currfeedurl="@productFeedUrl" data-id="{{productId}}" data-method="add" data-feedurl="@picknmixFeed" data-currency-code="{{currency}}"> 10769 + 10770 </div> 10771 </div> 10772 </div> 10773 {{else}} 10774 <button class="btn btn--add-to-cart js-product-amount-validation-btn {{disabledBuyButton}} {{#if useCustomCocktailProductCardDesign}}cocktail-product-buy-button{{/if}}" title="@Translate("Smartpage:Product.Buy", "Køb")" onclick="Cart.AddToCart(event, { id: '{{productId}}', variantId: '{{variantid}}', unitId: '{{unitId}}', productInfo: {{productInfo}}, quantity: getSelectedQuantity('{{productId}}@idSuffix'), SpPrimeur: '{{isPrimeur}}' }); {{facebookPixelAction}}" type="button" data-product-id="{{productId}}" data-one-unit-price="{{oneUnitPrice}}" data-volume-unit-price="{{volumeUnitPrice}}" data-volume-unit-threshold="{{kolli}}" data-currency-code="{{currency}}"> 10775 {{#if useCustomCocktailProductCardDesign}} 10776 <span>@Translate("Smartpage:Product.Cocktail.Buy", "Køb pakke")</span> 10777 {{else}} 10778 <span>@Translate("Smartpage:Product.Buy", "Køb")</span> 10779 {{/if}} 10780 </button> 10781 <span class="invalid-amount-tooltip-text">@Translate("Custom.Product.Buy.Tooltip.AmountInvalid", "Det samlede antal er ugyldigt. Klik for at ændre til det nærmest gyldige antal")</span> 10782 {{/if}} 10783 </div> 10784 {{/unless}} 10785 </div> 10786 </div> 10787 {{#if primeurDeliveryDate}} 10788 <div class="grid__col-12 incoming-primeur-date u-align-end u-no-padding"> 10789 <div class="incoming-primeur-date__date"> 10790 {{ primeurDeliveryDate }} 10791 </div> 10792 </div> 10793 {{/if}} 10794 </div> 10795 {{/unless}} 10796 {{/if}} 10797 {{#if bomSoldOutMessage}} 10798 <div class="grid__col-12 sold-out-message-container"> 10799 <div class="sold-out-message"> 10800 <span class="message">{{ bomSoldOutMessage }}</span> 10801 </div> 10802 </div> 10803 {{/if}} 10804 </div> 10805 } 10806 10807 @helper RenderGridViewItemActions(Dynamicweb.Frontend.ItemViewModel gridViewSettings) 10808 { 10809 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 10810 { 10811 @RenderGridViewItemPricesAndAddToCart(gridViewSettings) 10812 } 10813 } 10814 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 10815 @using Dynamicweb 10816 @using Dynamicweb.Core 10817 @using Dynamicweb.Rapido.Blocks.Components.General 10818 @using Dynamicweb.Rapido.Blocks 10819 @using Dynamicweb.Rapido.Blocks.Components 10820 @using Smartpage.Relewise.Services.Models 10821 10822 @functions{ 10823 BlocksPage productRecommendationSliderBlock = new BlocksPage(); 10824 Dynamicweb.Frontend.ItemViewModel gridViewSettingsRecommendationSlider = null; 10825 } 10826 10827 @helper RenderRecommendationSlider(Smartpage.Relewise.Services.Models.RecommendationItem recommendationItem, int preloaderElementsAmount = 0, Smartpage.PhilipsonWine.Ecommerce.ProductInformation.ExtendedProductViewModel extendedProductViewModel = null, int itemIndex = 0, bool hasMultipleRecommendationItems = false) 10828 { 10829 string marginStyle = "style='margin-top: 2rem; margin-bottom: 2rem;'"; 10830 bool isCocktailPack = extendedProductViewModel != null ? extendedProductViewModel.IsCocktailPack : false; 10831 if (isCocktailPack) 10832 { 10833 <div class="paragraph-container--full-width cocktail-product-recommendations"> 10834 <div class="@recommendationItem.GridClasses" @(recommendationItem.HideMargin ? string.Empty : marginStyle)> 10835 @RenderRecommendationSliderColumns(recommendationItem, preloaderElementsAmount, isCocktailPack) 10836 </div> 10837 </div> 10838 } 10839 else 10840 { 10841 <div class="@recommendationItem.GridClasses" @(recommendationItem.HideMargin ? string.Empty : marginStyle)> 10842 @RenderRecommendationSliderColumns(recommendationItem, preloaderElementsAmount, false, itemIndex, hasMultipleRecommendationItems) 10843 </div> 10844 } 10845 } 10846 10847 @helper RenderRecommendationSliderColumns(RecommendationItem recommendationItem, int preloaderElementsAmount, bool isCocktailPack = false, int itemIndex = 0, bool hasMultipleRecommendationItems = false) 10848 { 10849 string headline = recommendationItem.Headline; 10850 bool deactivateSwiper = recommendationItem.DisplayAsGrid && !recommendationItem.EnableSwiperInGridMode; 10851 10852 <div class="@recommendationItem.ColClasses js-product-slider-item @(recommendationItem.DisplayAsGrid ? "recommendations-grid-view-container" : "")"> 10853 @if (!string.IsNullOrEmpty(headline)) 10854 { 10855 string centerClass = recommendationItem.CenterHeadline ? "u-ta-center" : ""; 10856 string headlineColor = recommendationItem.HeadlineColor; 10857 string fontColor = !string.IsNullOrEmpty(headlineColor) ? "color: " + headlineColor + ";" : ""; 10858 10859 if (isCocktailPack) 10860 { 10861 int cocktailsPage = GetPageIdByNavigationTag("CocktailsPage"); 10862 string cocktailsPageLink = cocktailsPage > 0 ? "/Default.aspx?ID=" + cocktailsPage : ""; 10863 <div class="cocktail-pack-recommendation-header"> 10864 <h2 class="@centerClass" style="@fontColor">@headline</h2> 10865 <a href="@cocktailsPageLink" class="cocktail-pack-recommendation-button-text btn btn--tertiary dw-mod">@Translate("Smartpage:CocktailRecommendations.Button.SeeAllCocktailPacks", "Se alle drinks pakker") <i class="fa fa-arrow-right custom-product-info__icon"></i></a> 10866 </div> 10867 } 10868 else 10869 { 10870 if (!hasMultipleRecommendationItems) 10871 { 10872 string subHeadline = recommendationItem.SubHeadline; 10873 <div class="focused-heading-container"> 10874 <div class="focused-heading-line"></div> 10875 <div class="focused-heading-text"> 10876 @if (!string.IsNullOrEmpty(subHeadline)) 10877 { 10878 <p>@subHeadline</p> 10879 } 10880 <h2 class="@centerClass" style="@fontColor">@headline</h2> 10881 </div> 10882 <div class="focused-heading-line"></div> 10883 </div> 10884 } 10885 } 10886 } 10887 10888 @if (!string.IsNullOrEmpty(recommendationItem.APIRoute)) 10889 { 10890 10891 gridViewSettingsRecommendationSlider = Pageview.AreaSettings.GetItem("ProductList").GetItem("GridView"); 10892 10893 string feedUrl = recommendationItem.GetUrl(GetPageIdByNavigationTag("ProductsPageNoFacets")); 10894 10895 Block gridViewItem = new Block 10896 { 10897 Id = "GridViewItem", 10898 SortId = 10, 10899 Template = RenderGridViewItem(productRecommendationSliderBlock), 10900 SkipRenderBlocksList = true, 10901 BlocksList = new List<Block> { 10902 new Block 10903 { 10904 Id = "GridViewItemHiddenProperties", 10905 SortId = 10, 10906 Template = RenderGridViewItemHiddenProperties() 10907 }, 10908 new Block 10909 { 10910 Id = "GridViewItemImageContainer", 10911 SortId = 20, 10912 SkipRenderBlocksList = true, 10913 Template = RenderGridViewItemImageContainer(productRecommendationSliderBlock), 10914 BlocksList = new List<Block> 10915 { 10916 new Block 10917 { 10918 Id = "GridViewItemImage", 10919 SortId = 10, 10920 Template = RenderGridViewItemImage() 10921 } 10922 } 10923 }, 10924 new Block 10925 { 10926 Id = "GridViewItemFooter", 10927 SortId = 40, 10928 SkipRenderBlocksList = true, 10929 Template = RenderGridViewItemFooter(productRecommendationSliderBlock, gridViewSettingsRecommendationSlider), 10930 BlocksList = new List<Block> { 10931 new Block 10932 { 10933 Id = "GridViewItemActions", 10934 SortId = 10, 10935 Template = RenderGridViewItemActions(gridViewSettingsRecommendationSlider) 10936 } 10937 } 10938 } 10939 } 10940 }; 10941 10942 productRecommendationSliderBlock.Add(gridViewItem); 10943 10944 string swiperPrevButtonClass = recommendationItem.Id + "_SwiperButtonPrev"; 10945 string swiperNextButtonClass = recommendationItem.Id + "_SwiperButtonNext"; 10946 bool isCartPage = Pageview.ID == GetPageIdByNavigationTag("CartPage"); 10947 string preRenderContainerClasses = "js-product-slider-preloader"; 10948 10949 if (recommendationItem.DisplayAsGrid) 10950 { 10951 preRenderContainerClasses += " recommendations-grid-view-preloader recommendations-grid-view-preloader--loading"; 10952 } 10953 else 10954 { 10955 preRenderContainerClasses += " product-slider-preloader product-slider-preloader--loading"; 10956 } 10957 10958 if (recommendationItem.ActivatePodium) 10959 { 10960 preRenderContainerClasses += " podium-activated"; 10961 } 10962 10963 Dictionary<string, string> extraAttributes = new Dictionary<string, string>(); 10964 string multipleItemsContainerClass = ""; 10965 10966 if (hasMultipleRecommendationItems) 10967 { 10968 extraAttributes.Add("data-recommendation-item-index", HttpUtility.HtmlAttributeEncode(Converter.ToString(itemIndex))); 10969 multipleItemsContainerClass = " js-recommendations-container"; 10970 } 10971 10972 if (itemIndex > 1) 10973 { 10974 extraAttributes.Add("data-init-onload", "false"); 10975 } 10976 10977 bool isActiveByDefault = hasMultipleRecommendationItems && itemIndex == 1; 10978 if (isActiveByDefault) 10979 { 10980 multipleItemsContainerClass += " js-active-recommendation-item"; 10981 } 10982 10983 <div class="js-recommendations-handlebars js-handlebars-root-async grid@(multipleItemsContainerClass)" id="@recommendationItem.Id" data-initialized="@HttpUtility.HtmlAttributeEncode(Converter.ToString(isActiveByDefault).ToLower())" data-template="@("ProductContainer_" + recommendationItem.Id)" data-json-feed="@feedUrl" @ComponentMethods.AddAttributes(extraAttributes)></div> 10984 <div class="@preRenderContainerClasses"> 10985 @for (int i = 0; i < (Pageview.Device.ToString() == "Mobile" ? 1 : preloaderElementsAmount); i++) 10986 { 10987 <div class="pre-render-element product-slider-preloader-element"></div> 10988 } 10989 </div> 10990 10991 <script id="@("ProductContainer_" + recommendationItem.Id)" type="text/x-template"> 10992 <div class="swiper-container js-product-slider-container product-slider-container @recommendationItem.Id @(!recommendationItem.DisplayAsGrid ? "recommendations-slider " + recommendationItem.SwiperContainerClasses : "") @(deactivateSwiper ? "js-recommendations-deactivate-slider" : "")" data-swiper-config="@recommendationItem.GetLayout()"> 10993 {{#each .}} 10994 <div class="swiper-wrapper @(recommendationItem.DisplayAsGrid ? "recommendations-grid-wrapper" : "") @(recommendationItem.ActivatePodium ? "recommendations-podium-container" : "")"> 10995 {{#each ProductsContainer}} 10996 <div id="Product{{id}}" data-template="GridViewItem" data-preloader="overlay" class="product-list__grid-item dw-mod js-product-list-product product-list-product swiper-slide @(recommendationItem.DisplayAsGrid ? "product-slider-grid-view-item" : "")"> 10997 {{#each Product}} 10998 {{>GridViewItem}} 10999 {{/each}} 11000 </div> 11001 {{/each}} 11002 </div> 11003 <div class="swiper-pagination"></div> 11004 {{/each}} 11005 </div> 11006 @if (!deactivateSwiper) 11007 { 11008 string desktopCss = Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Desktop ? "custom-swiper-buttons-desktop" : ""; 11009 <div id="@swiperPrevButtonClass" class="swiper-button-prev @desktopCss"></div> 11010 <div id="@swiperNextButtonClass" class="swiper-button-next @desktopCss"></div> 11011 } 11012 </script> 11013 11014 @RenderBlockList(productRecommendationSliderBlock.BlocksRoot.BlocksList) 11015 11016 <script id="ProductSliderPreRenderContainer" type="text/x-template"> 11017 <div class="grid__col-auto"> 11018 <div class="pre-render-element pre-render-element--lg" style="height: 570px;"></div> 11019 </div> 11020 </script> 11021 11022 <script id="StickersContainer" type="text/x-template"> 11023 <div class="stickers-container stickers-container--{{{convertStickerPositionToClassName Position}}} dw-mod"> 11024 {{#Stickers}} 11025 {{>Sticker}} 11026 {{/Stickers}} 11027 </div> 11028 </script> 11029 11030 <script id="Sticker" type="text/x-template"> 11031 @Render(new Sticker { Title = "{{Title}}", CssClass = "{{CssClass}}" }) 11032 </script> 11033 } 11034 11035 </div> 11036 } 11037 11038 11039 @{ 11040 string addToCartNotificationType = Model.Area.Item.GetItem("Ecommerce").GetItem("MiniCart").GetList("AddToCartNotificationType") != null ? Model.Area.Item.GetItem("Ecommerce").GetItem("MiniCart").GetList("AddToCartNotificationType").SelectedValue : ""; 11041 string addToCartNotificationMiniCartLayout = Model.Area.Item.GetItem("Ecommerce").GetItem("MiniCart").GetList("Layout") != null ? Model.Area.Item.GetItem("Ecommerce").GetItem("MiniCart").GetList("Layout").SelectedValue : "dropdown"; 11042 bool addToCartHideCartIcon = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("HideCart"); 11043 11044 string id = "RecommendationsAddToCartSlider"; 11045 var recommendationItem = new RecommendationItem() 11046 { 11047 Id = id, 11048 CenterHeadline = true, 11049 Headline = Translate("Custom:ProductSlider.Recommendations.Headline." + id, "Andre købte også"), 11050 Label = Translate("Custom:ProductSlider.Recommendations.Headline." + id, "Anbefalinger Powerstep"), 11051 Limit = "20", 11052 APIRoute = "PurchasedWithProduct", 11053 NumberOfSlides = 2, 11054 Layout = RecommendationItem.SliderLayout.PowerStep, 11055 GridClasses = "grid u-full-height grid--justify-center", 11056 ColClasses = "grid__col-12 u-no-padding", 11057 HideMargin = true 11058 }; 11059 11060 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed() && !string.IsNullOrEmpty(addToCartNotificationType)) 11061 { 11062 if (addToCartNotificationType == "modal") 11063 { 11064 Block addToCartNotificationModal = new Block 11065 { 11066 Id = "AddToCartNotificationModal", 11067 Template = RenderAddToCartNotificationModal() 11068 }; 11069 11070 Block addToCartNotificationScript = new Block 11071 { 11072 Id = "AddToCartNotificationScript", 11073 Template = RenderAddToCartNotificationModalScript(recommendationItem) 11074 }; 11075 11076 Block freightMeterScript = new Block 11077 { 11078 Id = "FreightMeterScript", 11079 Template = RenderFreightMeterScript() 11080 }; 11081 11082 BlocksPage.GetBlockPage("Master").Add("MasterTopSnippets", addToCartNotificationModal); 11083 BlocksPage.GetBlockPage("Master").Add("MasterBottomSnippets", addToCartNotificationScript); 11084 BlocksPage.GetBlockPage("Master").Add("MasterBottomSnippets", freightMeterScript); 11085 } 11086 else if (addToCartNotificationType == "toggle" && addToCartNotificationMiniCartLayout != "none" && !addToCartHideCartIcon) 11087 { 11088 Block addToCartNotificationScript = new Block 11089 { 11090 Id = "AddToCartNotificationScript", 11091 Template = RenderAddToCartNotificationToggleScript() 11092 }; 11093 BlocksPage.GetBlockPage("Master").Add("MasterBottomSnippets", addToCartNotificationScript); 11094 } 11095 } 11096 11097 } 11098 11099 11100 @helper RenderAddToCartNotificationModal() 11101 { 11102 <div id="LastAddedProductModal" class="last-added-product-modal" data-template="LastAddedProductTemplate"></div> 11103 } 11104 11105 @helper RenderAddToCartNotificationModalScript(RecommendationItem recommendationItem) 11106 { 11107 int cartPageId = GetPageIdByNavigationTag("CartPage"); 11108 <script id="LastAddedProductTemplate" type="text/x-template"> 11109 @{ 11110 11111 Modal lastAddedProduct = new Modal 11112 { 11113 Id = "LastAddedProduct", 11114 Width = ModalWidth.Lg, 11115 BodyTemplate = Pageview.Device.ToString() == "Mobile" ? RenderMobileModalContent(recommendationItem) : RenderModalContent(recommendationItem), 11116 OnClose = "window.scrollLockDisable();" 11117 }; 11118 11119 @Render(lastAddedProduct) 11120 } 11121 </script> 11122 11123 int miniCartPageId = GetPageIdByNavigationTag("MiniCartFeed"); 11124 string feedUrl = "/Default.aspx?ID=" + miniCartPageId; 11125 <script> 11126 document.addEventListener('addToCart', function (event) { 11127 if (event.detail.lineNotAddedNotification != null) { 11128 showCartLineNotAddedModal(event.detail.lineNotAddedNotification); 11129 } else { 11130 // Show added to cart modal if not on carts page 11131 if (document.querySelector('.carts-page') == null) { 11132 Cart.ShowLastAddedProductModal(event.detail); 11133 } 11134 } 11135 }); 11136 11137 function closeModal(e) { 11138 if (e.classList.contains("js-toggle-last-added-product-modal")) { 11139 localStorage.setItem('LastAddedProductModalHidden', 'true'); 11140 var today = new Date(); 11141 var oneWeekFromNow = today.setDate(today.getDate() + 7); 11142 localStorage.setItem('LastAddedProductModal.ExpiresIn', JSON.stringify(oneWeekFromNow)); 11143 } 11144 11145 document.getElementById('LastAddedProductModalTrigger').checked = false; 11146 window.scrollLockDisable(); 11147 } 11148 </script> 11149 11150 string swiperPaginationClass = recommendationItem.Id + "_SwiperPagination"; 11151 string swiperPrevButtonClass = recommendationItem.Id + "_SwiperButtonPrev"; 11152 string swiperNextButtonClass = recommendationItem.Id + "_SwiperButtonNext"; 11153 11154 <script id="@("ProductContainer_" + recommendationItem.Id)" type="text/x-template"> 11155 <div class="@recommendationItem.GridClasses"> 11156 <div class="@recommendationItem.ColClasses"> 11157 <div class="recommendations"> 11158 <div id="@("SliderContainer_" + recommendationItem.Id)" class="swiper-container custom-swiper-container product-slider-container js-product-slider-container @recommendationItem.Id" data-swiper-config="@recommendationItem.GetLayout()"> 11159 {{#each .}} 11160 <div id="AddToCartRecommendations" class="swiper-wrapper powerstep"> 11161 {{#each ProductsContainer}} 11162 <div id="Product{{id}}" data-template="GridViewItem" data-preloader="overlay" class="product-list__grid-item dw-mod swiper-slide product-slider-grid-view-item product-card js-product-grid-item" data-product-id="{{productId}}"> 11163 {{#each Product}} 11164 {{>GridViewItem}} 11165 {{/each}} 11166 </div> 11167 {{/each}} 11168 </div> 11169 {{/each}} 11170 <div class="swiper-pagination @swiperPaginationClass"></div> 11171 </div> 11172 <div id="@swiperPrevButtonClass" class="swiper-button-prev"></div> 11173 <div id="@swiperNextButtonClass" class="swiper-button-next"></div> 11174 </div> 11175 </div> 11176 </div> 11177 </script> 11178 11179 } 11180 11181 @helper RenderModalContent(RecommendationItem recommendationItem) 11182 { 11183 int cartPageId = GetPageIdByNavigationTag("CartPage"); 11184 int miniCartPageId = GetPageIdByNavigationTag("MiniCartFeed"); 11185 bool activateFreightMeter = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetBoolean("ActivateFreightMeter"); 11186 11187 <div class="grid added-to-cart-section"> 11188 <div class="added-to-cart u-flex u-no-padding u-flex--align-center u-justify-content--center grid grid__col-12 u-flex--row"> 11189 <h3 class="grid__col-12 grid--justify-center added-to-cart-text">@RenderCheckmark() @Translate("Smartpage:LastAddedProductModal.AddedToCart", "Tilføjet til kurven")</h3> 11190 @if (activateFreightMeter) 11191 { 11192 <div class="js-handlebars-root freight-meter" id="freightMeterContainer"></div> 11193 } 11194 <div class="product-image-container grid__col-1"> 11195 {{#if EcomOrderLineFieldInput_SpPickAndMixGroupId1}} 11196 @Render(new Image { Path = "/Admin/Public/GetImage.ashx?Width=115&Height=115&Crop=5&DoNotUpscale=True&FillCanvas=False&Image=/Files/Images/philipsonwine/pickandmix/Kasse.png", Title = Translate("Smartpage:Checkout.PMXCart.Name", "Din egen vinkasse"), DisableImageEngine = true, CssClass = "product-image" }) 11197 {{else}} 11198 @if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["ProductId"])) 11199 { 11200 @Render(new Image { Path = "{{ productInfo.image }}", Link = "{{ productInfo.link }}", Title = "{{ productInfo.name }}", DisableImageEngine = true, CssClass = "product-image" }) 11201 } 11202 else 11203 { 11204 @Render(new Image { Path = "{{ productInfo.addToCartModalImage }}", Link = "{{ productInfo.link }}", Title = "{{ productInfo.name }}", DisableImageEngine = true, CssClass = "product-image" }) 11205 } 11206 {{/if}} 11207 </div> 11208 <div class="grid__col-5"> 11209 <div class="u-flex u-flex--column"> 11210 {{#if EcomOrderLineFieldInput_SpPickAndMixGroupId1}} 11211 <div>@Translate("Smartpage:Checkout.PMXCart.Name", "Din egen vinkasse")</div> 11212 {{else}} 11213 <div class="u-margin-right added-to-cart-quantity">{{quantity}} <span class="u-lowercase">{{unitId}}</span></div> 11214 {{#if productInfo.name}} 11215 <div class="powerstep-product-name">{{productInfo.name}}</div> 11216 {{else}} 11217 <div>{{name}}</div> 11218 {{/if}} 11219 {{#if productInfo.variantName}} 11220 <small class="u-margin-bottom-5px">{{productInfo.variantName}}</small> 11221 {{/if}} 11222 {{#if productInfo.unitName}} 11223 <small class="u-margin-bottom-5px">{{productInfo.unitName}}</small> 11224 {{/if}} 11225 {{/if}} 11226 </div> 11227 </div> 11228 <div class="grid__col-6 u-full-height"> 11229 <div class="u-full-width u-flex u-flex--row buttons"> 11230 @Render(new Button 11231 { 11232 ButtonType = ButtonType.Button, 11233 ButtonLayout = ButtonLayout.Secondary, 11234 Title = HttpUtility.HtmlAttributeEncode(Translate("Smartpage:LastAddedProductModal.ContinueShopping", "Shop videre")), 11235 CssClass = "u-pull--left u-no-margin btn-continue-shopping u-margin-right--lg white-button", 11236 OnClick = "closeModal(this)" 11237 }) 11238 @Render(new Link 11239 { 11240 Href = "/Default.aspx?ID=" + cartPageId, 11241 ButtonLayout = ButtonLayout.Primary, 11242 CssClass = "u-pull--right u-no-margin btn-go-to-checkout", 11243 Title = HttpUtility.HtmlAttributeEncode(Translate("Smartpage:LastAddedProductModal.GoToCart", "Gå til kurven")), 11244 OnClick = "closeModal(this)" 11245 }) 11246 </div> 11247 <button onclick="closeModal(this)" class="dont-show-again u-align-content-left u-font-size--xs js-toggle-last-added-product-modal"> 11248 @Translate("Smartpage:LastAddedProductModal.DontShowAgain", "Vis ikke igen") 11249 </button> 11250 </div> 11251 </div> 11252 </div> 11253 11254 <div> 11255 {{#if productInfo.hasCustomAddToCartModal}} 11256 <div class="custom-add-to-cart-modal-message"> 11257 <div> 11258 <p>{{{productInfo.customModalMessage}}}</p> 11259 </div> 11260 </div> 11261 {{else}} 11262 <div class="others-bought-section"> 11263 @RenderModalSubheading(recommendationItem) 11264 </div> 11265 {{/if}} 11266 </div> 11267 } 11268 11269 @helper RenderMobileModalContent(RecommendationItem recommendationItem) 11270 { 11271 int cartPageId = GetPageIdByNavigationTag("CartPage"); 11272 int miniCartPageId = GetPageIdByNavigationTag("MiniCartFeed"); 11273 bool activateFreightMeter = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetBoolean("ActivateFreightMeter"); 11274 11275 <div class="grid grid--align-center grid--justify-center added-to-cart-section"> 11276 <div class="added-to-cart u-flex u-no-padding u-flex--align-center u-justify-content--center grid__col-12 grid u-flex--row"> 11277 <div class="grid"> 11278 <h3 class="added-to-cart-text grid__col-12"> @RenderCheckmark() @Translate("Smartpage:LastAddedProductModal.AddedToCart", "Tilføjet til kurven")</h3> 11279 @if (activateFreightMeter) 11280 { 11281 <div class="js-handlebars-root freight-meter" id="freightMeterContainer"></div> 11282 } 11283 <div class="product-image-container grid__col-2"> 11284 {{#if EcomOrderLineFieldInput_SpPickAndMixGroupId1}} 11285 @Render(new Image { Path = "/Admin/Public/GetImage.ashx?Width=115&Height=115&Crop=5&DoNotUpscale=True&FillCanvas=False&Image=/Files/Images/philipsonwine/pickandmix/Kasse.png", Title = Translate("Smartpage:Checkout.PMXCart.Name", "Din egen vinkasse"), DisableImageEngine = true, CssClass = "product-image" }) 11286 {{else}} 11287 @if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["ProductId"])) 11288 { 11289 @Render(new Image { Path = "{{ productInfo.image }}", Link = "{{ productInfo.link }}", Title = "{{ productInfo.name }}", DisableImageEngine = true, CssClass = "product-image" }) 11290 } 11291 else 11292 { 11293 @Render(new Image { Path = "{{ productInfo.addToCartModalImage }}", Link = "{{ productInfo.link }}", Title = "{{ productInfo.name }}", DisableImageEngine = true, CssClass = "product-image" }) 11294 } 11295 {{/if}} 11296 </div> 11297 <div class="u-flex u-flex--column grid--justify-center grid__col-10"> 11298 {{#if EcomOrderLineFieldInput_SpPickAndMixGroupId1}} 11299 <div>@Translate("Smartpage:Checkout.PMXCart.Name", "Din egen vinkasse")</div> 11300 {{else}} 11301 <div class="u-margin-right added-to-cart-quantity">{{quantity}} <span class="u-lowercase">{{unitId}}</span></div> 11302 {{#if productInfo.name}} 11303 <div class="powerstep-product-name">{{productInfo.name}}</div> 11304 {{else}} 11305 <div>{{name}}</div> 11306 {{/if}} 11307 {{#if productInfo.variantName}} 11308 <small class="u-margin-bottom-5px">{{productInfo.variantName}}</small> 11309 {{/if}} 11310 {{#if productInfo.unitName}} 11311 <small class="u-margin-bottom-5px">{{productInfo.unitName}}</small> 11312 {{/if}} 11313 {{/if}} 11314 </div> 11315 </div> 11316 </div> 11317 </div> 11318 11319 <div> 11320 {{#if productInfo.hasCustomAddToCartModal}} 11321 <div class="custom-add-to-cart-modal-message"> 11322 <div> 11323 <p>{{{productInfo.customModalMessage}}}</p> 11324 </div> 11325 </div> 11326 {{else}} 11327 <div class="others-bought-section"> 11328 @RenderModalSubheading(recommendationItem) 11329 </div> 11330 {{/if}} 11331 </div> 11332 11333 <div class="grid__col-12 grid--justify-center u-no-padding bottom-actions"> 11334 <div class="u-flex u-flex--row buttons"> 11335 @Render(new Button 11336 { 11337 ButtonType = ButtonType.Button, 11338 ButtonLayout = ButtonLayout.Secondary, 11339 Title = HttpUtility.HtmlAttributeEncode(Translate("Smartpage:LastAddedProductModal.ContinueShopping", "Shop videre")), 11340 CssClass = "u-pull--left u-no-margin btn-continue-shopping u-margin-right--lg white-button", 11341 OnClick = "closeModal(this)" 11342 }) 11343 @Render(new Link 11344 { 11345 Href = "/Default.aspx?ID=" + cartPageId, 11346 ButtonLayout = ButtonLayout.Primary, 11347 CssClass = "u-pull--right u-no-margin btn-go-to-checkout", 11348 Title = HttpUtility.HtmlAttributeEncode(Translate("Smartpage:LastAddedProductModal.GoToCart", "Gå til kurven")), 11349 OnClick = "closeModal(this)" 11350 }) 11351 </div> 11352 11353 <button onclick="closeModal(this)" class="dont-show-again u-align-content-left u-font-size--xs js-toggle-last-added-product-modal"> 11354 @Translate("Smartpage:LastAddedProductModal.DontShowAgain", "Vis ikke igen") 11355 </button> 11356 </div> 11357 } 11358 11359 @helper RenderFreightMeterScript() 11360 { 11361 <script id="FreightMeter" type="text/x-template"> 11362 {{#.}} 11363 <div class="freight-message {{powerstepFreightMessageCssClass}}"> 11364 {{powerstepFreightMessage}} 11365 11366 {{#unless powerstepFreightMessageCssClass}} 11367 <span class="u-bold">@Translate("Smartpage:LastAddedProductModal.FreeFreight", "fri fragt")</span> 11368 {{/unless}} 11369 </div> 11370 <div class="progress-bar-container"> 11371 <div class="progress-bar-indicator" style="width:{{percentageFreeFreight}}%"></div> 11372 </div> 11373 {{/.}} 11374 </script> 11375 } 11376 11377 @{ 11378 11379 string cartPageId = GetPageIdByNavigationTag("CartPage").ToString(); 11380 11381 if (Dynamicweb.Context.Current.Items["Smartpage:LineAdjusted"] != null) 11382 { 11383 var lineAdjustedNotification = Dynamicweb.Context.Current.Items["Smartpage:LineAdjusted"] as List<LineAdjusted>; 11384 11385 <input type="checkbox" id="CartLineAdjustedModalTrigger" class="modal-trigger" checked> 11386 <div class="modal-container"> 11387 <label class="modal-overlay"></label> 11388 <div class="modal modal--lg modal-height--auto" id="CartLineAdjustedModal"> 11389 @foreach (LineAdjusted lineAdjusted in lineAdjustedNotification) 11390 { 11391 <div class="modal__header u-fs-18"> 11392 <div class="u-ta-center"> 11393 <strong><span class="u-underline"><span class="js-product-name">@lineAdjusted.ProductName</span>@Translate("Smartpage:CartLineAdjustedModal.AdjustedNotification", " kan ikke købes i det ønskede antal.")</span></strong> 11394 </div> 11395 </div> 11396 <div class="modal__body"> 11397 <div class="grid grid--justify-center"> 11398 <div class="grid__col-12 grid__col-lg-4-auto"> 11399 <div class="u-ta-center js-text-description u-margin-bottom"> 11400 <span>@String.Format(Translate("Smartpage:CartLineAdjustedModal.NewStock", "Der er desværre kun {0} stk. tilbage."), lineAdjusted.NewQuantity)</span><br /> 11401 </div> 11402 </div> 11403 </div> 11404 </div> 11405 11406 11407 } 11408 <a href="/Default.aspx?ID=@cartPageId" class="modal__close-btn u-margin-top-5" onclick="document.getElementById('CartLineAdjustedModalTrigger').checked = false;"></a> 11409 11410 <div class="grid"> 11411 <div class="grid__col-12-auto u-flex--row u-justify-content--center"> 11412 <div class="grid__col-6-auto"> 11413 <a href="/Default.aspx?ID=@cartPageId" class="btn btn--secondary u-no-margin--bottom dw-mod js-dismiss-modal" onclick="document.getElementById('CartLineAdjusteddModalTrigger').checked = false;">@Translate("Smartpage:CartLineAdjustedModal.Back", "Tilbage til kurv")</a> 11414 </div> 11415 </div> 11416 </div> 11417 </div> 11418 </div> 11419 11420 } 11421 11422 if (Dynamicweb.Context.Current.Items["Smartpage:RemovedInactiveLine"] != null) 11423 { 11424 var lineRemovedNotification = Dynamicweb.Context.Current.Items["Smartpage:RemovedInactiveLine"] as List<LineRemoved>; 11425 11426 <input type="checkbox" id="CartLineRemovedModalTrigger" class="modal-trigger" checked> 11427 <div class="modal-container"> 11428 <label class="modal-overlay"></label> 11429 <div class="modal modal--lg modal-height--auto" id="CartLineRemovedModal"> 11430 @foreach (LineRemoved lineRemoved in lineRemovedNotification) 11431 { 11432 string reason = lineRemoved.ReasonDescription == "NotInStock" ? "Varen er desværre blevet udsolgt i mellemtiden." : "Der er sket en fejl."; 11433 11434 <div class="modal__header u-fs-18"> 11435 <div class="u-ta-center"> 11436 <strong><span class="u-underline"><span class="js-product-name">@lineRemoved.ProductName</span>@Translate("Smartpage:CartLineRemovedModal.IsRemovedNotifacation", " er blevet fjernet fra kurven")</span></strong> 11437 </div> 11438 </div> 11439 <div class="modal__body"> 11440 <div class="grid grid--justify-center"> 11441 <div class="grid__col-12 grid__col-lg-4-auto"> 11442 <div class="u-ta-center js-text-description u-margin-bottom"> 11443 <span>@Translate("Smartpage:CartLineRemoval.CouldNotAdd", "Kunne ikke tilføje")</span> @lineRemoved.ProductName <br /> 11444 <span>@Translate("Smartpage:CartLineRemoval.Reason." + reason, reason)</span> 11445 </div> 11446 </div> 11447 </div> 11448 </div> 11449 11450 11451 <a href="/Default.aspx?ID=@cartPageId" class="modal__close-btn u-margin-top-5" onclick="document.getElementById('CartLineRemovedModalTrigger').checked = false;"></a> 11452 } 11453 <div class="grid"> 11454 <div class="grid__col-12-auto u-flex--row u-justify-content--center"> 11455 <div class="grid__col-6-auto"> 11456 <a href="/Default.aspx?ID=@cartPageId" class="btn btn--secondary u-no-margin--bottom dw-mod js-dismiss-modal" onclick="document.getElementById('CartLineRemovedModalTrigger').checked = false;">@Translate("Smartpage:CartLineRemovedModal.OK", "OK")</a> 11457 </div> 11458 </div> 11459 </div> 11460 </div> 11461 </div> 11462 11463 } 11464 11465 } 11466 11467 @helper RenderModalSubheading(RecommendationItem recommendationItem) 11468 { 11469 <div class="u-flex grid--align-center"> 11470 <div class="seperation-line u-margin-right--lg"></div> 11471 <h3 class="heading-over-slider grid--justify-center whitespace-nowrap">@recommendationItem.Headline</h3> 11472 <div class="seperation-line u-margin-left--lg"></div> 11473 </div> 11474 @RenderRecommendations(recommendationItem) 11475 11476 } 11477 11478 @helper RenderRecommendations(RecommendationItem recommendationItem) 11479 { 11480 string feedUrl = recommendationItem.GetUrl(GetPageIdByNavigationTag("ProductsPageNoFacets")); 11481 11482 <div class="product-slider-item js-product-slider-item js-recommendation-item-container" data-initialized="false"> 11483 <div id="@recommendationItem.Id" class="add-to-cart-slider" data-slides-amount="@recommendationItem.NumberOfSlides"> 11484 <div class="js-handlebars-root-async js-add-to-cart-product-slider grid" id="@recommendationItem.Id" data-template="@("ProductContainer_" + recommendationItem.Id)" data-json-feed="@feedUrl"></div> 11485 <div class="product-slider-preloader js-product-slider-preloader product-slider-preloader--loading"> 11486 <div class="preloader-overlay__icon js-product-slider-preloader-icon"></div> 11487 </div> 11488 </div> 11489 </div> 11490 } 11491 11492 11493 @helper RenderAddToCartNotificationToggleScript() 11494 { 11495 int miniCartFeedPageId = GetPageIdByNavigationTag("MiniCartFeed"); 11496 11497 <script> 11498 document.addEventListener('addToCart', function (event) { 11499 if (event.detail.lineNotAddedNotification != null) { 11500 showCartLineNotAddedModal(event.detail.lineNotAddedNotification); 11501 } else { 11502 Cart.ToggleMiniCart('miniCartTrigger', 'miniCart', 'cartCounter', '@miniCartFeedPageId'); 11503 } 11504 }); 11505 </script> 11506 } 11507 11508 @helper RenderCheckmark() 11509 { 11510 <svg class="added-to-cart-checkmark" width="25px" height="18px" viewBox="0 0 25 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 11511 <title>01130066-C57C-43F6-B6A2-489724630A18</title> 11512 <g id="Powerstep" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> 11513 <g transform="translate(-673.000000, -79.000000)" fill="#50A87D" id="Group-2"> 11514 <g transform="translate(532.000000, 30.000000)"> 11515 <g id="Group" transform="translate(62.279070, 31.000000)"> 11516 <g id="Tilføjet-til-kurven" transform="translate(78.720930, 13.000000)"> 11517 <path d="M0.359445042,14.8016255 C-0.119815014,14.3303213 -0.119815014,13.5661551 0.359445042,13.0948038 L2.0950309,11.3879821 C2.57429096,10.9166307 3.35140464,10.9166307 3.8306647,11.3879821 L9.20454246,16.6726046 L20.7147898,5.35347814 C21.1940499,4.88217395 21.9711636,4.88217395 22.4504236,5.35347814 L24.1860095,7.06029986 C24.6652696,7.53160404 24.6652696,8.29577025 24.1860095,8.76712158 L10.0723594,22.6465278 C9.59305136,23.1178319 8.81598562,23.1178319 8.33672556,22.6464806 L0.359445042,14.8016255 Z" id="Checkmark"></path> 11518 </g> 11519 </g> 11520 </g> 11521 </g> 11522 </g> 11523 </svg> 11524 } 11525 @inherits Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>> 11526 @using Dynamicweb.Rapido.Blocks.Extensibility 11527 @using Dynamicweb.Rapido.Blocks 11528 @using Dynamicweb.Ecommerce.Common 11529 @using Dynamicweb.Frontend.Navigation 11530 11531 11532 @{ 11533 BlocksPage referencesBlocksPage = BlocksPage.GetBlockPage("Master"); 11534 11535 Block masterScriptReferences = new Block() 11536 { 11537 Id = "MasterScriptReferences", 11538 SortId = 1, 11539 Template = RenderMasterScriptReferences() 11540 }; 11541 referencesBlocksPage.Add(MasterBlockId.MasterReferences, masterScriptReferences); 11542 11543 Block googleBreadcrumbSchema = new Block() 11544 { 11545 Id = "GoogleBreadcrumbSchema", 11546 SortId = 2, 11547 Template = RenderGoogleBreadcrumbSchema() 11548 }; 11549 referencesBlocksPage.Add(MasterBlockId.MasterReferences, googleBreadcrumbSchema); 11550 11551 } 11552 11553 @helper RenderGoogleBreadcrumbSchema() 11554 { 11555 var navigationSettings = new NavigationSettings(); 11556 navigationSettings.StartLevel = Pageview.Page.ID == GetPageIdByNavigationTag("ProductsPage") ? 1 : 2; 11557 navigationSettings.StopLevel = 10; 11558 navigationSettings.ExpandMode = ExpandMode.PathOnly; 11559 11560 @Navigation.RenderNavigation("../Navigation/BreadcrumbGoogle.cshtml", navigationSettings) 11561 } 11562 11563 @helper RenderMasterScriptReferences() 11564 { 11565 11566 var fileVersion = System.Web.HttpContext.Current.Cache["FileVersion"]; 11567 11568 <script src="/Files/Templates/Designs/Rapido/js/master.min.js?@fileVersion"></script> 11569 11570 if (Model.Area.Item.GetItem("Custom").GetBoolean("UseCustomJavascript")) 11571 { 11572 <script src="/Files/Templates/Designs/Rapido/js/custom.min.js?v=@fileVersion"></script> 11573 } 11574 11575 if (!string.IsNullOrEmpty(Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetString("PurchaseScript")) && !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["CompletedOrderId"])) 11576 { 11577 <script src="@Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetString("PurchaseScript")"></script> 11578 } 11579 } 11580 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 11581 11582 @using System 11583 @using System.Web 11584 @using System.Collections.Generic 11585 @using Dynamicweb.Core 11586 @using Dynamicweb.Rapido.Blocks.Extensibility 11587 @using Dynamicweb.Rapido.Blocks 11588 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 11589 @using Dynamicweb.Rapido.Services 11590 11591 @{ 11592 BlocksPage searchBlocksPage = BlocksPage.GetBlockPage("Master"); 11593 bool navigationItemsHideSearch = Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("HideSearch"); 11594 bool isFavoriteList = !string.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("ListID")); 11595 11596 if (!navigationItemsHideSearch || isFavoriteList) 11597 { 11598 Block masterSearchScriptTemplates = new Block() 11599 { 11600 Id = "MasterSearchScriptTemplates", 11601 SortId = 1, 11602 Template = RenderSearchScriptTemplates() 11603 }; 11604 11605 searchBlocksPage.Add(MasterBlockId.MasterBottomSnippets, masterSearchScriptTemplates); 11606 } 11607 } 11608 11609 @helper RenderSearchScriptTemplates() 11610 { 11611 int productsPageId = GetPageIdByNavigationTag("ProductsPage"); 11612 string contentSearchPageLink = GetPageIdByNavigationTag("ContentSearchResults") + "&Areaid=" + Model.Area.ID; 11613 bool useFacebookPixel = !string.IsNullOrWhiteSpace(Pageview.AreaSettings.GetItem("Settings").GetString("FacebookPixelID")); 11614 bool useGoogleTagManager = !string.IsNullOrEmpty(Model.Area.Item.GetItem("Settings").GetString("GoogleTagManagerID")); 11615 bool showPrice = !Pageview.AreaSettings.GetItem("Layout").GetBoolean("HidePriceInSearchResults"); 11616 bool showAddToCartButton = !Pageview.AreaSettings.GetItem("Layout").GetBoolean("HideAddToCartButton"); 11617 bool showViewButton = !Pageview.AreaSettings.GetItem("Layout").GetBoolean("HideViewButton"); 11618 bool showAddToDownloadButton = Pageview.AreaSettings.GetItem("Layout").GetBoolean("ShowAddToDownloadButton"); 11619 bool pointShopOnly = Pageview.AreaSettings.GetItem("Ecommerce").GetBoolean("PointShopOnly"); 11620 var uspList = Pageview.AreaSettings.GetItem("Custom").GetItems("USPList"); 11621 11622 <script id="SearchGroupsTemplate" type="text/x-template"> 11623 {{#.}} 11624 <li class="dropdown__item dw-mod" onclick="Search.UpdateGroupSelection(this)" data-group-id="{{id}}">{{name}}</li> 11625 {{/.}} 11626 </script> 11627 11628 <script id="SearchProductsTemplate" type="text/x-template"> 11629 {{#AnySpecificElements . 'ProductGridItemContainer'}} 11630 {{#each .}} 11631 {{#Product}} 11632 {{#ifCond template "!==" "SearchMore"}} 11633 <li class="dropdown__item dropdown__item--seperator dw-mod"> 11634 @if (useFacebookPixel) 11635 { 11636 <text>{{{facebookPixelSearch name number priceDouble currency searchParameter}}}</text> 11637 } 11638 @if (useGoogleTagManager) 11639 { 11640 <text>{{{googleEnchantImpression googleImpression}}}</text> 11641 } 11642 <div> 11643 <a href="{{link}}" 11644 class="js-typeahead-link u-color-inherit u-pull--left" 11645 onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" 11646 title="{{name}}{{#if variantName}}, {{variantName}}{{/if}}"> 11647 <div class="u-margin-right u-pull--left {{noimage}} u-hidden-xs u-hidden-xxs"><img class="b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=45&height=36&crop=5&FillCanvas=True&Compression=75&image={{image}}" alt="{{name}}{{#if variantName}}, {{variantName}}{{/if}}"></div> 11648 <div class="u-pull--left"> 11649 <div class="u-bold u-max-w220px u-truncate-text js-typeahead-name">{{name}}{{#if variantName}}, {{variantName}}{{/if}}</div> 11650 @if (showPrice && Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 11651 { 11652 if (pointShopOnly) 11653 { 11654 <text> 11655 {{#if havePointPrice}} 11656 <div> 11657 <span class="u-color--loyalty-points">{{points}}</span> @Translate("points") 11658 </div> 11659 {{else}} 11660 <small class="help-text u-no-margin">@Translate("Not available")</small> 11661 {{/if}} 11662 {{#unless canBePurchasedWithPoints}} 11663 {{#if havePointPrice}} 11664 <small class="help-text u-no-margin">@Translate("Not enough points to buy this")</small> 11665 {{/if}} 11666 {{/unless}} 11667 </text> 11668 } 11669 else 11670 { 11671 <div>{{price}}</div> 11672 } 11673 } 11674 </div> 11675 </a> 11676 <div class="u-margin-left u-pull--right"> 11677 @{ 11678 var viewBtn = new Link 11679 { 11680 Href = "{{link}}", 11681 OnClick = "{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}", 11682 ButtonLayout = ButtonLayout.Secondary, 11683 CssClass = "btn--condensed u-no-margin js-ignore-click-outside search btn--add-to-cart", 11684 Title = Translate("View") 11685 }; 11686 } 11687 @if (showAddToCartButton && Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 11688 { 11689 <text>{{#if hideAddToCartButton}}</text> 11690 @Render(viewBtn) 11691 <text>{{else}}</text> 11692 @Render(new AddToCartButton 11693 { 11694 HideTitle = true, 11695 ProductId = "{{productId}}", 11696 ProductInfo = "{{productInfo}}", 11697 BuyForPoints = pointShopOnly, 11698 OnClick = "{{facebookPixelAction}}", 11699 CssClass = "u-no-margin js-ignore-click-outside search btn--add-to-cart", 11700 Title = Translate("Buy"), 11701 ExtraAttributes = new Dictionary<string, string> 11702 { 11703 { "{{disabledBuyButton}}", "" } 11704 } 11705 }) 11706 <text>{{/if}}</text> 11707 } 11708 else if (showViewButton) 11709 { 11710 @Render(viewBtn) 11711 } 11712 @if (showAddToDownloadButton) 11713 { 11714 <button type="button" class="btn btn--primary u-no-margin btn--condensed dw-mod js-add-to-downloads search" title="@Translate("Add")" data-product-id="{{productId}}"> 11715 @Translate("Buy") 11716 </button> 11717 } 11718 </div> 11719 </div> 11720 </li> 11721 {{/ifCond}} 11722 {{#ifCond template "===" "SearchMore"}} 11723 {{>SearchMoreProducts}} 11724 {{/ifCond}} 11725 {{/Product}} 11726 {{/each}} 11727 {{else}} 11728 <li class="dropdown__item dropdown__item--seperator dropdown__item--not-selectable js-no-result dw-mod"> 11729 @Translate("Your search gave 0 results") 11730 </li> 11731 {{/AnySpecificElements}} 11732 </script> 11733 11734 <script id="SearchFavoriteProductsTemplate" type="text/x-template"> 11735 {{#AnySpecificElements . 'ProductDetailsItemContainer'}} 11736 {{#each .}} 11737 {{#Product}} 11738 {{#ifCond template "!==" "SearchMore"}} 11739 <li class="dropdown__item dropdown__item--seperator dw-mod"> 11740 @if (useFacebookPixel) 11741 { 11742 <text>{{{facebookPixelSearch name number priceDouble currency searchParameter}}}</text> 11743 } 11744 @if (useGoogleTagManager) 11745 { 11746 <text>{{{googleEnchantImpression googleImpression}}}</text> 11747 } 11748 <div> 11749 <a href="{{link}}" 11750 class="js-typeahead-link u-color-inherit u-pull--left" 11751 onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}" 11752 title="{{name}}{{#if variantName}}, {{variantName}}{{/if}}"> 11753 <div class="u-margin-right u-pull--left {{noimage}} u-hidden-xs u-hidden-xxs"><img class="b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=45&height=36&crop=5&FillCanvas=True&Compression=75&image={{image}}" alt="{{name}}{{#if variantName}}, {{variantName}}{{/if}}"></div> 11754 <div class="u-pull--left"> 11755 <div class="u-bold u-max-w220px u-truncate-text js-typeahead-name">{{name}}{{#if variantName}}, {{variantName}}{{/if}}</div> 11756 @if (showPrice && Dynamicweb.Rapido.Services.User.IsPricesAllowed()) 11757 { 11758 if (pointShopOnly) 11759 { 11760 <text> 11761 {{#if havePointPrice}} 11762 <div> 11763 <span class="u-color--loyalty-points">{{points}}</span> @Translate("points") 11764 </div> 11765 {{else}} 11766 <small class="help-text u-no-margin">@Translate("Not available")</small> 11767 {{/if}} 11768 {{#unless canBePurchasedWithPoints}} 11769 {{#if havePointPrice}} 11770 <small class="help-text u-no-margin">@Translate("Not enough points to buy this")</small> 11771 {{/if}} 11772 {{/unless}} 11773 </text> 11774 } 11775 else 11776 { 11777 <div>{{price}}</div> 11778 } 11779 } 11780 </div> 11781 </a> 11782 <div class="u-margin-left u-pull--right"> 11783 @{ 11784 var viewBtnFavorites = new Link 11785 { 11786 Href = "{{link}}", 11787 OnClick = "{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event){{/if}}", 11788 ButtonLayout = ButtonLayout.Secondary, 11789 CssClass = "btn--condensed u-no-margin js-ignore-click-outside search btn--add-to-cart", 11790 Title = Translate("View") 11791 }; 11792 } 11793 @if (showAddToCartButton && Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 11794 { 11795 <text>{{#if hideAddToCartButton}}</text> 11796 @Render(viewBtnFavorites) 11797 <text>{{else}}</text> 11798 @Render(new AddToCartButton 11799 { 11800 HideTitle = true, 11801 ProductId = "{{productId}}", 11802 ProductInfo = "{{productInfo}}", 11803 BuyForPoints = pointShopOnly, 11804 OnClick = "{{facebookPixelAction}}", 11805 CssClass = "u-no-margin js-ignore-click-outside search btn--add-to-cart", 11806 Title = Translate("Buy"), 11807 ExtraAttributes = new Dictionary<string, string> 11808 { 11809 { "{{disabledBuyButton}}", "" } 11810 } 11811 }) 11812 <text>{{/if}}</text> 11813 } 11814 else if (showViewButton) 11815 { 11816 @Render(viewBtnFavorites) 11817 } 11818 @if (showAddToDownloadButton) 11819 { 11820 <button type="button" class="btn btn--primary u-no-margin btn--condensed dw-mod js-add-to-downloads search" title="@Translate("Add")" data-product-id="{{productId}}"> 11821 @Translate("Buy") 11822 </button> 11823 } 11824 </div> 11825 </div> 11826 </li> 11827 {{/ifCond}} 11828 {{#ifCond template "===" "SearchMore"}} 11829 {{>SearchMoreProducts}} 11830 {{/ifCond}} 11831 {{/Product}} 11832 {{/each}} 11833 {{else}} 11834 <li class="dropdown__item dropdown__item--seperator dropdown__item--not-selectable js-no-result dw-mod"> 11835 @Translate("Your search gave 0 results") 11836 </li> 11837 {{/AnySpecificElements}} 11838 </script> 11839 11840 <script id="SearchMoreProducts" type="text/x-template"> 11841 <li class="dropdown__item dropdown__item--not-selectable {{stickToBottom}} dw-mod"> 11842 <a href="/Default.aspx?ID=@productsPageId&Search={{searchParameter}}&GroupID={{groupId}}" class="btn btn--primary btn--full u-no-margin dw-mod js-typeahead-link search"> 11843 @Translate("View all") 11844 </a> 11845 </li> 11846 </script> 11847 11848 <script id="SearchMorePages" type="text/x-template"> 11849 <li class="dropdown__item dropdown__item--not-selectable {{stickToBottom}} dw-mod"> 11850 <a href="/Default.aspx?ID=@contentSearchPageLink&Search={{searchParameter}}" class="btn btn--primary btn--full u-no-margin dw-mod js-typeahead-link search"> 11851 @Translate("View all") 11852 </a> 11853 </li> 11854 </script> 11855 11856 <script id="SearchPagesTemplate" type="text/x-template"> 11857 {{#each .}} 11858 {{#ifCond template "!==" "SearchMore"}} 11859 <li class="dropdown__item dropdown__item--seperator dropdown__item--no-padding dw-mod"> 11860 <a href="/Default.aspx?ID={{id}}" class="js-typeahead-link dropdown__link u-color-inherit"> 11861 <div class="u-margin-right"><i class="fa {{icon}} u-w20px u-ta-center"></i></div> 11862 <div class="u-bold u-truncate-text u-max-w220px js-typeahead-name">{{name}}</div> 11863 </a> 11864 </li> 11865 {{/ifCond}} 11866 {{#ifCond template "===" "SearchMore"}} 11867 {{>SearchMorePages}} 11868 {{/ifCond}} 11869 {{else}} 11870 <li class="dropdown__item dropdown__item--seperator dropdown__item--not-selectable js-no-result dw-mod"> 11871 @Translate("Your search gave 0 results") 11872 </li> 11873 {{/each}} 11874 </script> 11875 11876 <script id="SearchPagesTemplateWrap" type="text/x-template"> 11877 <div class="dropdown__column-header">@Translate("Pages")</div> 11878 <ul class="dropdown__list u-min-w220px u-full-width u-margin-bottom u-height--auto u-flex-grow--1 dw-mod"> 11879 {{>SearchPagesTemplate}} 11880 </ul> 11881 </script> 11882 11883 <script id="SearchProductsTemplateWrap" type="text/x-template"> 11884 <div class="dropdown__column-header">@Translate("Products")</div> 11885 <ul class="dropdown__list u-min-w220px u-full-width u-margin-bottom u-height--auto u-flex-grow--1 dw-mod"> 11886 {{>SearchProductsTemplate}} 11887 </ul> 11888 </script> 11889 <script id="SearchSpellCheckerSuggestionsTemplateWrap" type="text/x-template"> 11890 {{#AnySpecificElements . 'SpellCheckerSuggestion'}} 11891 <div class="dropdown__column-header u-bold">@Translate("Smartpage:Search.SpellCheckerSuggestions.Header", "Mente du?")</div> 11892 <ul class="dropdown__list u-min-w220px u-full-width u-margin-bottom u-height--auto u-flex-grow--1 dw-mod u-padding js-ignore-click-outside spell-checker-suggestions"> 11893 {{>SearchSpellCheckerSuggestionsTemplate}} 11894 </ul> 11895 {{/AnySpecificElements}} 11896 </script> 11897 11898 <script id="SearchSpellCheckerSuggestionsTemplate" type="text/x-template"> 11899 {{#each .}} 11900 {{#SpellCheckerSuggestion}} 11901 <div class="js-ignore-click-outside js-spell-checker-suggestion spell-checker-suggestion"> 11902 {{#if @@last}} 11903 <span>{{suggestion}}</span> 11904 {{else}} 11905 <span>{{suggestion}}</span>, 11906 {{/if}} 11907 </div> 11908 {{/SpellCheckerSuggestion}} 11909 {{/each}} 11910 </script> 11911 11912 var imagePrefix = "/Admin/Public/GetImage.ashx?width=150&amp;height=300&amp;crop=5&amp;Compression=75&amp;FillCanvas=true&amp;DoNotUpscale=true&amp;image="; 11913 11914 // CDN 11915 var cdnUrl = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetString("CDNUrl"); 11916 bool cdnActivate = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetBoolean("CDNActivate"); 11917 if (!string.IsNullOrWhiteSpace(cdnUrl) && cdnActivate) 11918 { 11919 imagePrefix = cdnUrl + imagePrefix; 11920 } 11921 11922 string columnCss = Pageview.Device.ToString() == "Mobile" ? "grid__col--bleed" : "grid__col--bleed-y"; 11923 11924 <script id="SearchResultsTypeAheadWithFilters" type="text/x-template"> 11925 {{#.}} 11926 <div class="grid__col-3 u-padding-left-none"> 11927 <div class="search-modal-result__title grid__col-12"> 11928 <h2 class="search-modal-header u-padding-left-none"> 11929 {{searchTermHeader}} 11930 </h2> 11931 </div> 11932 <div id="SearchTermPredictions" class="search-term-predictions"> 11933 <ul class="u-padding-none u-margin-top max-height-overflow"> 11934 {{#SearchTermPredictions}} 11935 <li class="u-flex whitespace-nowrap"> 11936 <a class="u-flex link" href="/Default.aspx?Id=@productsPageId&Search={{Term}}"> 11937 <img class="u-margin-right" src="/Files/Images/SvgIcons/Link-arrow.svg" /> 11938 <div class="js-search-term-prediction whitespace-nowrap">{{Term}}</div> 11939 </a> 11940 </li> 11941 {{/SearchTermPredictions}} 11942 </ul> 11943 </div> 11944 <div> 11945 <h2 class="grid__col-12 u-no-margin custom-text-style facet-header">@Translate("Custom:Search.Modal.Filters.Header", "Filtre")</h2> 11946 <input type="checkbox" id="CheckFacetGroups" class="js-remember-state u-hidden" data-expand="CheckFacetGroups" /> 11947 <div class="grid__col-12 search-facets-container facets-container facets-container--left expandable--collapsed dw-mod" data-trigger="CheckFacetGroups"> 11948 {{#FacetGroups}} 11949 <input type="hidden" class="js-remove-facet-parameters_{{queryParameter}}" value="{{queryParameter}}" data-type="{{template}}" /> 11950 <input type="checkbox" id="OptionsGroup_{{name}}" class="expand-trigger js-remember-state" {{defaultState}} /> 11951 <div class="expand-container facets-container__box dw-mod js-filter custom-border"> 11952 <label class="expand-container__btn facets-container__header dw-mod js-facets-container-header" for="OptionsGroup_{{name}}">{{name}}</label> 11953 <div class="expand-container__content dw-mod"> 11954 <div class="u-margin {{showFilter}}"> 11955 <input type="text" class="u-full-width u-no-margin custom-border" onkeyup="Filter.FilterItems(event)" placeholder="@Translate("Search")" /> 11956 </div> 11957 <div class="facets-container__list dw-mod {{template}}"> 11958 {{#FacetOptions}} 11959 {{#ifCond template "===" "Checkboxes"}} 11960 {{>SearchFacetsCheckboxes}} 11961 {{/ifCond}} 11962 {{/FacetOptions}} 11963 <div class="u-hidden js-filter-not-found"> 11964 @Translate("Your search gave 0 results") 11965 </div> 11966 </div> 11967 </div> 11968 </div> 11969 {{/FacetGroups}} 11970 </div> 11971 <label for="CheckFacetGroups" class="btn btn--primary btn--full u-no-margin dw-mod js-expand-hide facets-container-trigger facets-expander" data-trigger="CheckFacetGroups"> 11972 @Translate("Select filters") 11973 <i class="facets-filter-icon"></i> 11974 </label> 11975 <label for="CheckFacetGroups" class="btn btn--primary btn--full u-no-margin dw-mod expandable--collapsed facets-container-trigger facets-expander" data-trigger="CheckFacetGroups"> 11976 @Translate("Close filters") 11977 <i class="facets-filter-icon"></i> 11978 </label> 11979 </div> 11980 {{#unless beforeSearch}} 11981 <div class="links-section"> 11982 <h2 class="search-modal-header u-padding-left-none"> 11983 @Translate("Smartpage:Search.Modal.Links.Header", "Inspiration & hjælp") 11984 </h2> 11985 <ul class="u-padding-none u-margin-top"> 11986 @foreach (var usp in uspList) 11987 { 11988 var icon = usp.GetFile("Icon"); 11989 <li class="u-flex whitespace-nowrap"> 11990 @if (!string.IsNullOrWhiteSpace(usp.GetString("Link"))) 11991 { 11992 <a class="u-flex link" href="@usp.GetString("Link")"> 11993 @{ 11994 if (icon != null) 11995 { 11996 <img class="u-margin-right" src="@icon.Path" alt="@HttpUtility.HtmlAttributeEncode(usp.GetString("Label"))" /> 11997 } 11998 else 11999 { 12000 <i class="fa fa-check u-margin-right u-flex u-flex--align-center"></i> 12001 } 12002 } 12003 @usp.GetString("Label") 12004 </a> 12005 } 12006 else 12007 { 12008 if (icon != null) 12009 { 12010 <img class="u-margin-right" src="@icon.Path" alt="@HttpUtility.HtmlAttributeEncode(usp.GetString("Label"))" /> 12011 } 12012 else 12013 { 12014 <i class="fa fa-check u-margin-right u-flex u-flex--align-center"></i> 12015 } @usp.GetString("Label") 12016 } 12017 </li> 12018 12019 } 12020 </ul> 12021 </div> 12022 {{/unless}} 12023 </div> 12024 <div class="grid grid__col-9"> 12025 <div class="search-modal-result__title grid__col-12"> 12026 {{#if header}} 12027 <h2 class="search-modal-header"> 12028 {{header}} 12029 </h2> 12030 {{/if}} 12031 {{#if searchHeader}} 12032 <a class="u-underline see-all-link" href="/Default.aspx?ID=@productsPageId&Search={{searchParameter}}"> 12033 {{searchHeader}} 12034 </a> 12035 {{/if}} 12036 </div> 12037 <div id="SearchProductsContainer" class="products grid__col-12" data-template="SearchResultsProductsOnly"> 12038 {{#if hits}} 12039 {{> SearchResultsProductsOnly this}} 12040 </div> 12041 {{#if searchParameter}} 12042 {{#if totalProductsCount}} 12043 <div class="grid__col-12 @columnCss show-more {{nextdisabled}}"> 12044 <div class="show-more-counter-text"> 12045 @Translate("Smartpage:Counter.HaveSeen", "Du har set") <strong class="js-curr-amount-products @(!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString.Get("ListID")) ? "js-favorite-product-list-products-counter" : "")">{{currentProducts}}</strong> 12046 @Translate("Smartpage:Counter.OutOf", "af") <strong>{{totalProductsCount}}</strong> @Translate("Smartpage.Counter.Products", "produkter") 12047 </div> 12048 <a href="{{nextPageClean}}" id="LoadMoreButton" class="btn btn--secondary load-more-button js-search-modal-load-more-button dw-mod" data-current="{{currentPage}}" data-page-size="{{pageSize}}" data-total="{{totalPages}}" data-container="SearchProductsContainer" data-feed-url="{{moreFeedFullUrl}}" onclick="LoadMore.Next(event, this, 'undefined', 'searchModal')" {{nextdisabled}}>@Translate("Smartpage:Productlist.LoadMore", "Load more")</a> 12049 </div> 12050 {{/if}} 12051 <div class="grid__col-12 search-more-button"> 12052 <a href="/Default.aspx?ID=@productsPageId&Search={{searchParameter}}" class="btn btn--primary btn--full u-no-margin dw-mod js-typeahead-link js-typeahead-with-filters-link search"> 12053 @Translate("Smartpage:Search.ShowAllButton.Text", "Se alle {{totalProductsCount}} resultater") 12054 </a> 12055 </div> 12056 {{/if}} 12057 {{else}} 12058 <span>@Translate("Smartpage:Search.NoMatch", "Intet matchede") <b> {{searchParameter}} </b> @Translate("Smartpage:Search.NoMatch.Suggestion", "... prøv en anden søgning!")</span> 12059 {{/if}} 12060 </div> 12061 {{/.}} 12062 </script> 12063 12064 <script id="SearchResultsProductsOnly" type="text/x-template"> 12065 {{#.}} 12066 {{#if hits}} 12067 {{#ProductsContainerList}} 12068 {{#Product}} 12069 <div class="grid__col-4"> 12070 <a class="search-product grid" href="{{link}}" onclick="{{#if googleImpression}} googleEnchantImpressionClick({{googleImpression}}, event, true) {{/if}}" title="{{{name}}}"> 12071 <div class="search-product__image grid__col-3 u-no-padding {{bomProductClass}} {{eventClass}} {{cocktailClass}}"> 12072 <div class="grid-image" style="background-image: url('@imagePrefix{{image}}');" alt="{{name}}"></div> 12073 </div> 12074 <div class="search-product__info grid__col-9 u-no-padding"> 12075 <div class="labels"> 12076 {{#ProductRibbons}} 12077 <div class="top-label"> 12078 <div class="top-label__label top-label__label" style="background-color:{{RibbonBgColor}}; color:{{RibbonTextColor}}"> 12079 {{#if RibbonCustomRank}} 12080 <div class="custom-label-icon">{{RibbonCustomRank}}</div> 12081 {{/if}} 12082 {{RibbonText}} 12083 {{#if TooltipText}} 12084 <i class="fal fa-question-circle info-icon js-tooltip tooltip-icon tooltip-icon--product-list" data-tooltip-placement="{{TooltipPlacement}}" data-tooltip-content="{{TooltipText}}"></i> 12085 {{/if}} 12086 </div> 12087 </div> 12088 {{/ProductRibbons}} 12089 </div> 12090 <div class="search-product__name js-typeahead-search-product-name"> 12091 {{name}} 12092 </div> 12093 {{#unless eventProduct}} 12094 {{#if bomItemSavings}} 12095 <div class="savings">@Translate("Smartpage:ProductList.Product.Save", "SPAR") <strong>{{bomItemSavingsFormatted}}</strong></div> 12096 {{else if savings}} 12097 <div class="savings">@Translate("Smartpage:ProductList.Product.Save", "SPAR") <strong>{{savings}}</strong> @Translate("Smartpage:ProductList.Product.PerUnit", "PR. FL.")</div> 12098 {{else}} 12099 {{/if}} 12100 {{/unless}} 12101 <div class="search-product__price"> 12102 <div>{{price}}{{#if isSubscription}}@Translate("Smartpage:Checkout.PerMonth", "/md"){{/if}}</div> 12103 <div class="quantity-price"> 12104 {{{quantityDescription}}} 12105 </div> 12106 </div> 12107 </div> 12108 </a> 12109 </div> 12110 {{/Product}} 12111 {{/ProductsContainerList}} 12112 {{/if}} 12113 {{/.}} 12114 </script> 12115 12116 string searchType = !string.IsNullOrEmpty(Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Layout").GetRawValueString("TopSearch")) ? Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Layout").GetRawValueString("TopSearch") : "productSearch"; 12117 if (searchType == "productSearchWithFilters") 12118 { 12119 <script id="SearchFacetsCheckboxes" type="text/x-template"> 12120 <div class="form__field-group u-no-margin dw-mod"> 12121 <input type="checkbox" class="{{selected}} js-checkbox-facet checkbox-facet__checkbox form__control dw-mod" onclick="Facets.UpdateFacets(this);" id="{{queryParameter}}{{value}}" name="{{queryParameter}}" value="[{{value}}]" {{selected}} {{disabled}} data-products-count="{{count}}"> 12122 <label class="{{disabled}} checkbox-facet dw-mod" data-filter-value="{{label}}" for="{{queryParameter}}{{value}}"> 12123 <span class="checkbox-facet__label dw-mod">{{label}}</span> 12124 <span class="checkbox-facet__count dw-mod">({{count}})</span> 12125 </label> 12126 </div> 12127 </script> 12128 } 12129 12130 <script id="SearchResultsTypeAhead" type="text/x-template"> 12131 {{#.}} 12132 <div class="grid__col-3 u-padding-left-none"> 12133 <div class="search-modal-result__title grid__col-12"> 12134 <h2 class="search-modal-header u-padding-left-none"> 12135 {{searchTermHeader}} 12136 </h2> 12137 </div> 12138 <div id="SearchTermPredictions" class="search-term-predictions"> 12139 <ul class="u-padding-none u-margin-top"> 12140 {{#SearchTermPredictions}} 12141 <li class="u-flex whitespace-nowrap"> 12142 <a class="u-flex link" href="/Default.aspx?Id=@productsPageId&Search={{Term}}"> 12143 <img class="u-margin-right" src="/Files/Images/SvgIcons/Link-arrow.svg" /> 12144 <div class="js-search-term-prediction whitespace-nowrap">{{Term}}</div> 12145 </a> 12146 </li> 12147 {{/SearchTermPredictions}} 12148 </ul> 12149 </div> 12150 {{#unless beforeSearch}} 12151 <div class="links-section"> 12152 <h2 class="search-modal-header u-padding-left-none"> 12153 @Translate("Smartpage:Search.Modal.Links.Header", "Inspiration & hjælp") 12154 </h2> 12155 <ul class="u-padding-none u-margin-top"> 12156 @foreach (var usp in uspList) 12157 { 12158 var icon = usp.GetFile("Icon"); 12159 <li class="u-flex whitespace-nowrap"> 12160 @if (!string.IsNullOrWhiteSpace(usp.GetString("Link"))) 12161 { 12162 <a class="u-flex link" href="@usp.GetString("Link")"> 12163 @{ 12164 if (icon != null) 12165 { 12166 <img class="u-margin-right" src="@icon.Path" alt="@HttpUtility.HtmlAttributeEncode(usp.GetString("Label"))" /> 12167 } 12168 else 12169 { 12170 <i class="fa fa-check u-margin-right u-flex u-flex--align-center"></i> 12171 } 12172 } 12173 @usp.GetString("Label") 12174 </a> 12175 } 12176 else 12177 { 12178 if (icon != null) 12179 { 12180 <img class="u-margin-right" src="@icon.Path" alt="@HttpUtility.HtmlAttributeEncode(usp.GetString("Label"))" /> 12181 } 12182 else 12183 { 12184 <i class="fa fa-check u-margin-right u-flex u-flex--align-center"></i> 12185 } @usp.GetString("Label") 12186 } 12187 </li> 12188 12189 } 12190 </ul> 12191 </div> 12192 {{/unless}} 12193 </div> 12194 <div class="grid grid__col-9"> 12195 <div class="search-modal-result__title grid__col-12"> 12196 {{#if header}} 12197 <h2 class="search-modal-header"> 12198 {{header}} 12199 </h2> 12200 {{/if}} 12201 {{#if searchHeader}} 12202 <a class="u-underline see-all-link" href="/Default.aspx?ID=@productsPageId&Search={{searchParameter}}"> 12203 {{searchHeader}} 12204 </a> 12205 {{/if}} 12206 </div> 12207 <div class="products grid__col-12"> 12208 {{#if hits}} 12209 {{> SearchResultsProductsOnly this}} 12210 </div> 12211 {{#if searchParameter}} 12212 <div class="grid__col-12 search-more-button"> 12213 <a href="/Default.aspx?ID=@productsPageId&Search={{searchParameter}}" class="btn btn--primary btn--full u-no-margin dw-mod js-typeahead-link search"> 12214 @Translate("Smartpage:Search.ShowAllButton.Text", "Se alle {{totalProductsCount}} resultater") 12215 </a> 12216 </div> 12217 {{/if}} 12218 {{else}} 12219 <span>@Translate("Smartpage:Search.NoMatch", "Intet matchede") <b> {{searchParameter}} </b> @Translate("Smartpage:Search.NoMatch.Suggestion", "... prøv en anden søgning!")</span> 12220 {{/if}} 12221 </div> 12222 {{/.}} 12223 </script> 12224 12225 12226 12227 <script id="SearchResultsTypeAheadMobile" type="text/x-template"> 12228 {{#.}} 12229 <div class="typeahead-search-mobile"> 12230 {{#if hits}} 12231 {{#if beforeSearch}} 12232 <div class="typeahead-search-recommendations-title">{{header}}</div> 12233 {{else}} 12234 <div class="typeahead-search-alternate-query"> 12235 @Translate("Smartpage:Search.ShowingResults", "Viser søgeresultater for") <strong>"{{searchParameter}}"</strong>: 12236 </div> 12237 <div class="typeahead-bubble-container"> 12238 <div class="typeahead-bubble-wrapper js-search-category" data-element-id="searchProducts" onclick='window.setSearchCategory(this)'> 12239 <div class="typeahead-talk-bubble js-bubble selected"> 12240 <p class="typeahead-bubble-text">Produkter</p> 12241 </div> 12242 <div class="triangle js-triangle selected"></div> 12243 </div> 12244 12245 @*Use this later when implementing more search categories*@ 12246 @*<div class="typeahead-bubble-wrapper js-search-category" data-element-id="searchCategories" onclick='window.setSearchCategory(this)'> 12247 <div class="typeahead-talk-bubble js-bubble"> 12248 <p class="typeahead-bubble-text">Kategorier</p> 12249 </div> 12250 <div class="triangle js-triangle selected"></div> 12251 </div> 12252 12253 <div class="typeahead-bubble-wrapper js-search-category" data-element-id="SpRegionDescription" onclick='window.setSearchCategory(this)'> 12254 <div class="typeahead-talk-bubble js-bubble"> 12255 <p class="typeahead-bubble-text">Områder</p> 12256 </div> 12257 <div class="triangle js-triangle selected"></div> 12258 </div> 12259 12260 <div class="typeahead-bubble-wrapper js-search-category" data-element-id="SpProducerName" onclick='window.setSearchCategory(this)'> 12261 <div class="typeahead-talk-bubble js-bubble"> 12262 <p class="typeahead-bubble-text">Producenter</p> 12263 </div> 12264 <div class="triangle js-triangle selected"></div> 12265 </div> 12266 12267 <div class="typeahead-bubble-wrapper js-search-category" data-element-id="SpGrapePrimary" onclick='window.setSearchCategory(this)'> 12268 <div class="typeahead-talk-bubble js-bubble"> 12269 <p class="typeahead-bubble-text">Druer</p> 12270 </div> 12271 <div class="triangle js-triangle selected"></div> 12272 </div>*@ 12273 </div> 12274 {{/if}} 12275 <div class="typeahead-search-grid"> 12276 @* Extra search category example *@ 12277 @*<div class="typeahead-search-col js-search-results" id="searchCategories"> 12278 <h2>test test</h2> 12279 </div>*@ 12280 <div class="typeahead-search-col typeahead-flex-left js-search-results active" id="searchProducts"> 12281 <div class="typeahead-search-products"> 12282 {{#ProductsContainer}} 12283 {{#GroupedProducts}} 12284 <div class="typeahead-search-title">{{Category}}</div> 12285 {{#Products}} 12286 <a href="{{ link }}" onclick="{{#if googleImpression}}googleEnchantImpressionClick({{googleImpression}}, event, true){{/if}}"> 12287 <div class="typeahead-search-product"> 12288 <div class="typeahead-search-product-image-container"> 12289 <div class="typeahead-search-product-image" style="background-image: url('{{ image }}');"></div> 12290 </div> 12291 <div class="typeahead-search-product-info"> 12292 <div class="typeahead-search-product-name js-typeahead-search-product-name">{{ name }}</div> 12293 {{#unless ../../../beforeSearch}} 12294 <div class="typeahead-price-wrapper"> 12295 <div class="typeahead-search-product-price">{{price}}</div> 12296 <div class="typeahead-search-product-kolli"> 12297 {{{quantityDescription}}} 12298 </div> 12299 </div> 12300 {{/unless}} 12301 </div> 12302 <div class="typeahead-guillemet"> 12303 » 12304 </div> 12305 </div> 12306 </a> 12307 {{/Products}} 12308 {{/GroupedProducts}} 12309 {{/ProductsContainer}} 12310 {{#if showAll}} 12311 <div class="typeahead-search-more-results typeahead-search-key-selectable"> 12312 <a class="search-more-link" href="/produkter?Search={{searchParameter}}"> 12313 @Translate("Smartpage:Search.SeeAllResults", "Se alle søgeresultater") 12314 </a> 12315 </div> 12316 {{/if}} 12317 </div> 12318 </div> 12319 </div> 12320 {{else}} 12321 <div class="typeahead-search-no-results"> 12322 @Translate("Smartpage:Search.NoMatch", "Intet matchede") <b>{{searchParameter}}</b> @Translate("Smartpage:Search.NoMatch.Suggestion", "... prøv en anden søgning!") 12323 </div> 12324 {{/if}} 12325 </div> 12326 {{/.}} 12327 </script> 12328 12329 <script id="ProductSearchPreRenderContainer" type="text/x-template"> 12330 <div class="search-pre-render-container"> 12331 <div class="grid__col-3 u-padding-left-none pre-render-element--search-left-side"> 12332 <div class="pre-render-element pre-render-element--search-header u-margin-top"></div> 12333 <div class="pre-render-element pre-render-element--search-terms"></div> 12334 </div> 12335 <div class="grid grid__col-9 pre-render-element--search-right-side"> 12336 <div class="pre-render-element pre-render-element--search-header u-margin-top"></div> 12337 <div class="pre-render-element--search-products-container"> 12338 @for (int i = 0; i < 9; i++) 12339 { 12340 <div class="pre-render-element pre-render-element--search-product"></div> 12341 } 12342 </div> 12343 </div> 12344 </div> 12345 </script> 12346 } 12347 12348 @using Dynamicweb.Rapido.Blocks.Components 12349 @using Dynamicweb.Rapido.Blocks.Components.General 12350 @using Dynamicweb.Rapido.Blocks 12351 @using System.IO 12352 12353 12354 @using Dynamicweb.Rapido.Blocks.Components.General 12355 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 12356 12357 12358 @* Component *@ 12359 12360 @helper RenderVariantMatrix(VariantMatrix settings) { 12361 if (settings != null) 12362 { 12363 int productLoopCounter = 0; 12364 int groupCount = 0; 12365 List<VariantOption> firstDimension = new List<VariantOption>(); 12366 List<VariantOption> secondDimension = new List<VariantOption>(); 12367 List<VariantOption> thirdDimension = new List<VariantOption>(); 12368 12369 foreach (VariantGroup variantGroup in settings.GetVariantGroups()) 12370 { 12371 foreach (VariantOption variantOptions in variantGroup.GetVariantOptions()) 12372 { 12373 if (groupCount == 0) { 12374 firstDimension.Add(variantOptions); 12375 } 12376 if (groupCount == 1) 12377 { 12378 secondDimension.Add(variantOptions); 12379 } 12380 if (groupCount == 2) 12381 { 12382 thirdDimension.Add(variantOptions); 12383 } 12384 } 12385 groupCount++; 12386 } 12387 12388 int rowCount = 0; 12389 int columnCount = 0; 12390 12391 <script> 12392 var variantsCollection = []; 12393 </script> 12394 12395 <table class="table table--compact js-variants-matrix dw-mod" id="VariantMatrixTable_@settings.ProductId"> 12396 @if (groupCount == 1) 12397 { 12398 <tbody> 12399 @foreach (VariantOption firstVariantOption in firstDimension) 12400 { 12401 var variantId = firstVariantOption.Id; 12402 <tr> 12403 <td class="u-bold"> 12404 @firstVariantOption.Name 12405 </td> 12406 <td> 12407 @RenderVariantMatrixQuantityField(variantId, settings, productLoopCounter, rowCount, columnCount) 12408 </td> 12409 </tr> 12410 productLoopCounter++; 12411 } 12412 12413 <tr> 12414 <td>&nbsp;</td> 12415 <td> 12416 <div class="qty-field js-total-qty-column-@columnCount dw-mod">0</div> 12417 </td> 12418 </tr> 12419 </tbody> 12420 } 12421 @if (groupCount == 2) 12422 { 12423 <thead> 12424 <tr> 12425 <td>&nbsp;</td> 12426 @foreach (VariantOption variant in secondDimension) 12427 { 12428 <td>@variant.Name</td> 12429 } 12430 </tr> 12431 </thead> 12432 <tbody> 12433 @foreach (VariantOption firstVariantOption in firstDimension) 12434 { 12435 string variantId = ""; 12436 columnCount = 0; 12437 12438 <tr> 12439 <td class="u-min-w120px">@firstVariantOption.Name</td> 12440 12441 @foreach (VariantOption secondVariantOption in secondDimension) 12442 { 12443 variantId = firstVariantOption.Id + "." + secondVariantOption.Id; 12444 <td> 12445 @RenderVariantMatrixQuantityField(variantId, settings, productLoopCounter, rowCount, columnCount) 12446 </td> 12447 12448 columnCount++; 12449 12450 productLoopCounter++; 12451 } 12452 12453 <td> 12454 <div class="qty-field js-total-qty-row-@rowCount dw-mod">0</div> 12455 </td> 12456 </tr> 12457 12458 rowCount++; 12459 } 12460 12461 @{ 12462 columnCount = 0; 12463 } 12464 12465 <tr> 12466 <td>&nbsp;</td> 12467 @foreach (VariantOption secondVariantOption in secondDimension) 12468 { 12469 <td> 12470 <div class="qty-field js-total-qty-column-@columnCount dw-mod">0</div> 12471 </td> 12472 12473 columnCount++; 12474 } 12475 <td>&nbsp;</td> 12476 </tr> 12477 </tbody> 12478 } 12479 @if (groupCount == 3) 12480 { 12481 <thead> 12482 <tr> 12483 <td>&nbsp;</td> 12484 @foreach (VariantOption thirdVariantOption in thirdDimension) 12485 { 12486 <td>@thirdVariantOption.Name</td> 12487 } 12488 </tr> 12489 </thead> 12490 <tbody> 12491 @foreach (VariantOption firstVariantOption in firstDimension) 12492 { 12493 int colspan = (thirdDimension.Count + 1); 12494 12495 <tr> 12496 <td colspan="@colspan" class="u-color-light-gray--bg u-bold">@firstVariantOption.Name</td> 12497 </tr> 12498 12499 foreach (VariantOption secondVariantOption in secondDimension) 12500 { 12501 string variantId = ""; 12502 columnCount = 0; 12503 12504 <tr> 12505 <td class="u-min-w120px">@secondVariantOption.Name</td> 12506 12507 @foreach (VariantOption thirdVariantOption in thirdDimension) 12508 { 12509 variantId = firstVariantOption.Id + "." + secondVariantOption.Id + "." + thirdVariantOption.Id; 12510 12511 <td> 12512 @RenderVariantMatrixQuantityField(variantId, settings, productLoopCounter, rowCount, columnCount) 12513 </td> 12514 12515 columnCount++; 12516 productLoopCounter++; 12517 } 12518 12519 <td> 12520 <div class="qty-field js-total-qty-row-@rowCount dw-mod">0</div> 12521 </td> 12522 </tr> 12523 rowCount++; 12524 } 12525 } 12526 12527 @{ 12528 columnCount = 0; 12529 } 12530 12531 <tr> 12532 <td>&nbsp;</td> 12533 @foreach (VariantOption thirdVariantOption in thirdDimension) 12534 { 12535 <td> 12536 <div class="qty-field js-total-qty-column-@columnCount dw-mod">0</div> 12537 </td> 12538 12539 columnCount++; 12540 } 12541 <td>&nbsp;</td> 12542 </tr> 12543 </tbody> 12544 } 12545 </table> 12546 12547 <script> 12548 document.addEventListener("DOMContentLoaded", function (event) { 12549 MatrixUpdateQuantity("@settings.ProductId"); 12550 }); 12551 12552 MatrixUpdateQuantity = function (productId) { 12553 var currentMatrix = document.getElementById("VariantMatrixTable_" + productId); 12554 var allQtyFields = currentMatrix.getElementsByClassName("js-qty"); 12555 12556 var qtyRowArr = []; 12557 var qtyColumnArr = []; 12558 12559 var totalQty = 0; 12560 12561 for (var i = 0; i < allQtyFields.length; i++) { 12562 qtyRowArr[allQtyFields[i].getAttribute("data-qty-row-group")] = 0; 12563 qtyColumnArr[allQtyFields[i].getAttribute("data-qty-column-group")] = 0; 12564 } 12565 12566 for (var i = 0; i < allQtyFields.length; i++) { 12567 qtyRowArr[allQtyFields[i].getAttribute("data-qty-row-group")] += parseFloat(allQtyFields[i].value); 12568 qtyColumnArr[allQtyFields[i].getAttribute("data-qty-column-group")] += parseFloat(allQtyFields[i].value); 12569 totalQty += parseFloat(allQtyFields[i].value); 12570 } 12571 12572 //Update row counters 12573 for (var i = 0; i < qtyRowArr.length; i++) { 12574 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-row-" + i)[0]; 12575 12576 if (qtyRowArr[i] != undefined && qtyCounter != null) { 12577 var currentCount = qtyCounter.innerHTML; 12578 qtyCounter.innerHTML = qtyRowArr[i]; 12579 12580 if (currentCount != qtyCounter.innerHTML) { 12581 qtyCounter.classList.add("qty-field--active"); 12582 } 12583 } 12584 12585 } 12586 12587 //Update column counters 12588 for (var i = 0; i < qtyColumnArr.length; i++) { 12589 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-column-" + i)[0]; 12590 12591 if (qtyColumnArr[i] != undefined && qtyCounter != null) { 12592 var currentCount = qtyCounter.innerHTML; 12593 qtyCounter.innerHTML = qtyColumnArr[i]; 12594 12595 if (currentCount != qtyCounter.innerHTML) { 12596 qtyCounter.classList.add("qty-field--active"); 12597 } 12598 } 12599 } 12600 12601 if (document.getElementById("TotalQtyCount_" + productId)) { 12602 document.getElementById("TotalQtyCount_" + productId).innerHTML = totalQty; 12603 } 12604 12605 //Clean up animations 12606 setTimeout(function () { 12607 for (var i = 0; i < qtyRowArr.length; i++) { 12608 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-row-" + i)[0]; 12609 if (qtyCounter != null) { 12610 qtyCounter.classList.remove("qty-field--active"); 12611 } 12612 } 12613 for (var i = 0; i < qtyColumnArr.length; i++) { 12614 var qtyCounter = currentMatrix.getElementsByClassName("js-total-qty-column-" + i)[0]; 12615 if (qtyCounter != null) { 12616 qtyCounter.classList.remove("qty-field--active"); 12617 } 12618 } 12619 }, 1000); 12620 } 12621 </script> 12622 } 12623 } 12624 12625 @helper RenderVariantMatrixQuantityField(string variantId, VariantMatrix settings, int productLoopCounter, int rowCount, int columnCount) 12626 { 12627 string loopCount = productLoopCounter.ToString(); 12628 12629 bool combinationFound = false; 12630 double stock = 0; 12631 double quantityValue = 0; 12632 string note = ""; 12633 12634 VariantProduct variantProduct = null; 12635 12636 if (settings.GetVariantProducts().TryGetValue(variantId, out variantProduct)) 12637 { 12638 stock = variantProduct.Stock; 12639 quantityValue = variantProduct.Quantity; 12640 combinationFound = true; 12641 } 12642 12643 if (combinationFound) 12644 { 12645 <input type="hidden" name="ProductLoopCounter@(loopCount)" value="@loopCount" /> 12646 <input type="hidden" name="ProductID@(loopCount)" value="@settings.ProductId" /> 12647 <input type="hidden" name="VariantID@(loopCount)" value="@variantId" /> 12648 <input type="hidden" name="CurrentNote@(loopCount)" id="CurrentNote_@(settings.ProductId)_@variantId" value="@note" /> 12649 <input type="number" name="Quantity@(loopCount)" id="Quantity_@(settings.ProductId)_@variantId" value="@quantityValue" min="0" class="js-qty u-no-margin u-full-max-width" style="width: 100%; max-width: 100%" onkeyup="MatrixUpdateQuantity('@settings.ProductId')" onmouseup="MatrixUpdateQuantity('@settings.ProductId')" data-qty-row-group="@rowCount" data-qty-column-group="@columnCount"> 12650 12651 if (stock != 0) 12652 { 12653 <small>@Translate("Stock") @stock</small> 12654 } 12655 12656 <script> 12657 var variants = '{ "ProductId" :' + '"@settings.ProductId"' + ', "VariantId": ' + '"@variantId"' +'}'; 12658 variantsCollection.push(variants); 12659 document.getElementById("Quantity_@(settings.ProductId)_@variantId").closest(".js-variants-matrix").setAttribute("data-variants-collection", "[" + variantsCollection + "]" ); 12660 </script> 12661 } 12662 else 12663 { 12664 <div class="use-btn-height" style="background-color: #a8a8a8"></div> 12665 } 12666 } 12667 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 12668 12669 @* Component *@ 12670 12671 @helper RenderAddToCart(AddToCart settings) 12672 { 12673 //set Id for quantity selector to get it's value from button 12674 if (settings.QuantitySelector != null) 12675 { 12676 if (string.IsNullOrEmpty(settings.QuantitySelector.Id)) 12677 { 12678 settings.QuantitySelector.Id = Guid.NewGuid().ToString("N"); 12679 } 12680 12681 settings.AddButton.QuantitySelectorId = settings.QuantitySelector.Id; 12682 12683 if (settings.Disabled) 12684 { 12685 settings.QuantitySelector.Disabled = true; 12686 } 12687 12688 if (string.IsNullOrEmpty(settings.QuantitySelector.Name)) 12689 { 12690 settings.QuantitySelector.Name = settings.QuantitySelector.Id; 12691 } 12692 } 12693 12694 if (settings.Disabled) 12695 { 12696 settings.AddButton.Disabled = true; 12697 } 12698 12699 settings.AddButton.CssClass += " btn--condensed"; 12700 12701 //unitsSelector 12702 if (settings.UnitSelector != null) 12703 { 12704 if (settings.Disabled) 12705 { 12706 settings.QuantitySelector.Disabled = true; 12707 } 12708 } 12709 12710 <div class="buttons-collection @settings.WrapperCssClass" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 12711 @if (settings.UnitSelector != null) 12712 { 12713 @Render(settings.UnitSelector) 12714 } 12715 @if (settings.QuantitySelector != null) 12716 { 12717 @Render(settings.QuantitySelector) 12718 } 12719 @Render(settings.AddButton) 12720 </div> 12721 } 12722 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 12723 12724 @* Component *@ 12725 12726 @helper RenderAddToCartButton(AddToCartButton settings) 12727 { 12728 if (!settings.HideTitle) 12729 { 12730 if (string.IsNullOrEmpty(settings.Title)) 12731 { 12732 if (settings.BuyForPoints) 12733 { 12734 settings.Title = Translate("Buy with points"); 12735 } 12736 else 12737 { 12738 settings.Title = Translate("Add to cart"); 12739 } 12740 } 12741 } 12742 else 12743 { 12744 settings.Title = ""; 12745 } 12746 12747 if (settings.Icon == null) 12748 { 12749 settings.Icon = new Icon(); 12750 settings.Icon.LabelPosition = Dynamicweb.Rapido.Blocks.Components.General.IconLabelPosition.After; 12751 } 12752 12753 if (string.IsNullOrEmpty(settings.Icon.Name)) 12754 { 12755 settings.Icon.Name = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("CartIcon").SelectedValue; 12756 } 12757 12758 settings.OnClick = "Cart.AddToCart(event, { " + 12759 "id: '" + settings.ProductId + "'," + 12760 (!string.IsNullOrEmpty(settings.VariantId) ? "variantId: '" + settings.VariantId + "'," : "") + 12761 (!string.IsNullOrEmpty(settings.UnitId) ? "unitId: '" + settings.UnitId + "'," : "") + 12762 (settings.BuyForPoints ? "buyForPoints: true," : "") + 12763 (!string.IsNullOrEmpty(settings.ProductInfo) ? "productInfo: " + settings.ProductInfo + "," : "") + 12764 "quantity: " + (string.IsNullOrEmpty(settings.QuantitySelectorId) ? "1" : "parseFloat(document.getElementById('" + settings.QuantitySelectorId + "').value)") + 12765 "});" + settings.OnClick; 12766 12767 @RenderButton(settings) 12768 } 12769 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 12770 12771 @* Component *@ 12772 12773 @helper RenderUnitSelector(UnitSelector settings) 12774 { 12775 if (string.IsNullOrEmpty(settings.Id)) 12776 { 12777 settings.Id = Guid.NewGuid().ToString("N"); 12778 } 12779 var disabledClass = settings.Disabled ? "disabled" : ""; 12780 12781 <input type="checkbox" id="@settings.Id" class="dropdown-trigger" /> 12782 <div class="dropdown unit-selector @settings.CssClass @disabledClass dw-mod" @ComponentMethods.AddAttributes(settings.ExtraAttributes)> 12783 <label class="dropdown__header dropdown__btn dropdown__btn--unit-selector dw-mod" for="@settings.Id">@settings.SelectedOption</label> 12784 <div class="dropdown__content dw-mod"> 12785 @settings.OptionsContent 12786 </div> 12787 <label class="dropdown-trigger-off" for="@settings.Id"></label> 12788 </div> 12789 } 12790 @using System.Reflection 12791 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 12792 12793 @* Component *@ 12794 12795 @helper RenderQuantitySelector(QuantitySelector settings) 12796 { 12797 var attributes = new Dictionary<string, string>(); 12798 12799 /*base settings*/ 12800 if (!string.IsNullOrEmpty(settings.Id)) { attributes.Add("id", settings.Id); } 12801 if (!string.IsNullOrEmpty(settings.OnClick)) { attributes.Add("onclick", settings.OnClick); } 12802 if (!string.IsNullOrEmpty(settings.OnChange)) { attributes.Add("onchange", settings.OnChange); } 12803 if (settings.Disabled) { attributes.Add("disabled", "true"); } 12804 if (settings.Required) { attributes.Add("required", "true"); } 12805 if (!string.IsNullOrEmpty(settings.Name)) { attributes.Add("name", settings.Name); } 12806 /*end*/ 12807 12808 if (!string.IsNullOrEmpty(settings.OnKeyUp)) { attributes.Add("onkeyup", settings.OnKeyUp); } 12809 if (!string.IsNullOrEmpty(settings.OnInput)) { attributes.Add("oninput", settings.OnInput); } 12810 if (!string.IsNullOrEmpty(settings.OnFocus)) { attributes.Add("onfocus", settings.OnFocus); } 12811 if (settings.ReadOnly) { attributes.Add("readonly", "true"); } 12812 if (settings.Max != null) { attributes.Add("max", settings.Max.ToString()); } 12813 if (settings.Min == null) { settings.Min = 1; } 12814 attributes.Add("min", settings.Min.ToString()); 12815 if (settings.Step != null && !string.IsNullOrEmpty(settings.Step.ToString())) { attributes.Add("step", settings.Step.ToString()); } 12816 if (settings.Value == null) { settings.Value = 1; } 12817 attributes.Add("value", settings.Value.ToString()); 12818 attributes.Add("type", "number"); 12819 12820 var resultAttributes = attributes.Concat(settings.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 12821 12822 <input @ComponentMethods.AddAttributes(resultAttributes) class="@settings.CssClass dw-mod" /> 12823 } 12824 @using Dynamicweb.Rapido.Blocks.Components 12825 12826 @using Dynamicweb.Frontend 12827 @using Dynamicweb.Frontend.Devices 12828 @using Dynamicweb.Rapido.Blocks.Components.Ecommerce 12829 @using Dynamicweb.Rapido.Blocks.Components.General 12830 @using System.Collections.Generic; 12831 12832 @* Component *@ 12833 12834 @helper RenderCustomerCenterList(CustomerCenterList settings) 12835 { 12836 bool isTouchDevice = Pageview.Device.ToString() == "Mobile" || Pageview.Device.ToString() == "Tablet" ? true : false; 12837 string hideActions = isTouchDevice ? "u-block" : ""; 12838 12839 <table class="table data-list dw-mod"> 12840 @if (settings.GetHeaders().Length > 0) { 12841 <thead> 12842 <tr class="u-bold"> 12843 @foreach (CustomerCenterListHeaderItem header in settings.GetHeaders()) 12844 { 12845 var attributes = new Dictionary<string, string>(); 12846 if (!string.IsNullOrEmpty(header.Id)) { attributes.Add("id", header.Id); } 12847 if (!string.IsNullOrEmpty(header.CssClass)) { attributes.Add("class", header.CssClass); } 12848 attributes.Add("align", header.Align.ToString()); 12849 attributes = attributes.Concat(header.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 12850 12851 <td @ComponentMethods.AddAttributes(attributes)>@header.Title</td> 12852 } 12853 </tr> 12854 </thead> 12855 } 12856 @foreach (CustomerCenterListItem listItem in settings.GetItems()) 12857 { 12858 int columnCount = 0; 12859 int totalColumns = listItem.GetInfoItems().Length; 12860 string rowHasActions = listItem.GetActions().Length > 0 ? "data-list__item--has-acions" : ""; 12861 listItem.Id = !string.IsNullOrEmpty(listItem.Id) ? listItem.Id : Guid.NewGuid().ToString("N"); 12862 12863 var attributes = new Dictionary<string, string>(); 12864 if (!string.IsNullOrEmpty(listItem.Title)) { attributes.Add("title", listItem.Title); }; 12865 12866 attributes = attributes.Concat(listItem.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 12867 <tbody class="data-list__item @rowHasActions @listItem.CssClass dw-mod" @ComponentMethods.AddAttributes(attributes)> 12868 <tr> 12869 @if (!string.IsNullOrEmpty(listItem.Title) || !string.IsNullOrEmpty(listItem.Description)) { 12870 <td rowspan="2" onclick="@listItem.OnClick" class="data-list__main-item dw-mod"> 12871 @if (!string.IsNullOrEmpty(listItem.Title)) { 12872 <div class="u-bold">@listItem.Title</div> 12873 } 12874 @if (!string.IsNullOrEmpty(listItem.Description)) { 12875 <div>@listItem.Description</div> 12876 } 12877 </td> 12878 } 12879 12880 @foreach (CustomerCenterListInfoItem infoItem in listItem.GetInfoItems()) 12881 { 12882 var infoAttributes = new Dictionary<string, string>(); 12883 if (!string.IsNullOrEmpty(infoItem.Id)) { infoAttributes.Add("id", infoItem.Id); }; 12884 if (!string.IsNullOrEmpty(infoItem.OnClick)) { infoAttributes.Add("onclick", infoItem.OnClick); }; 12885 infoAttributes.Add("align", infoItem.Align.ToString()); 12886 12887 infoAttributes = infoAttributes.Concat(infoItem.ExtraAttributes).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.Last().Value); 12888 string columnClick = columnCount < (totalColumns-1) ? "onclick=\"" + listItem.OnClick + "\"" : ""; 12889 12890 <td @ComponentMethods.AddAttributes(infoAttributes) @columnClick class="data-list__info-item dw-mod"> 12891 @if (!string.IsNullOrEmpty(infoItem.Title)) { 12892 <div>@infoItem.Title</div> 12893 } 12894 @if (!string.IsNullOrEmpty(infoItem.Subtitle)) { 12895 <div><small>@infoItem.Subtitle</small></div> 12896 } 12897 </td> 12898 12899 columnCount++; 12900 } 12901 </tr> 12902 <tr> 12903 <td colspan="7" align="right" class="u-va-bottom u-no-border"> 12904 <div class="data-list__actions @hideActions dw-mod" id="ActionsMenu_@listItem.Id"> 12905 @foreach (ButtonBase action in listItem.GetActions()) 12906 { 12907 action.ButtonLayout = ButtonLayout.LinkClean; 12908 action.CssClass += " data-list__action-button link"; 12909 12910 @Render(action) 12911 } 12912 </div> 12913 </td> 12914 </tr> 12915 </tbody> 12916 } 12917 </table> 12918 } 12919 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 12920 @using System.Web 12921 @using Dynamicweb.Rapido.Blocks.Extensibility 12922 @using Dynamicweb.Rapido.Blocks 12923 @using Dynamicweb.Core 12924 @using System.Linq 12925 @using Dynamicweb.Frontend 12926 12927 @functions{ 12928 public class SommifyConfig 12929 { 12930 public string ApiKey { get; set; } 12931 public string Position { get; set; } 12932 public string Localization { get; set; } 12933 public string Currency { get; set; } 12934 public string SalesWeight { get; set; } 12935 public string MiniCartFeedPageId { get; set; } 12936 public bool EnableChatFunction { get; set; } 12937 public bool EnableFullScreen { get; set; } 12938 public Dictionary<string, List<string>> Prompts { get; set; } 12939 public string GoogleImpression { get; set; } 12940 } 12941 12942 public class GoogleImpression 12943 { 12944 public string Email { get; set; } 12945 public string Guid { get; set; } 12946 public string ShopId { get; set; } 12947 public string AreaId { get; set; } 12948 public string Origin { get; set; } 12949 public string Device { get; set; } 12950 } 12951 12952 public class InternationalTelephoneConfig 12953 { 12954 public string UtilsJsUrl { get; set; } 12955 public string InitialCountry { get; set; } 12956 public string SelectedCountryAriaLabel { get; set; } 12957 public string NoCountrySelected { get; set; } 12958 public string CountryListAriaLabel { get; set; } 12959 public string SearchPlaceholder { get; set; } 12960 public string ZeroSearchResults { get; set; } 12961 public string ErrorMessageIsPossible { get; set; } 12962 public string ErrorMessageInvalidCountryCode { get; set; } 12963 public string ErrorMessageTooShort { get; set; } 12964 public string ErrorMessageTooLong { get; set; } 12965 public string ErrorMessageIsPossibleLocalOnly { get; set; } 12966 public string ErrorMessageInvalidLength { get; set; } 12967 public bool StrictMode { get; set; } 12968 } 12969 } 12970 12971 @{ 12972 BlocksPage bottomSnippetsBlocksPage = BlocksPage.GetBlockPage("Master"); 12973 12974 Block primaryBottomSnippets = new Block() 12975 { 12976 Id = "MasterJavascriptInitializers", 12977 SortId = 100, 12978 Template = RenderPrimaryBottomSnippets() 12979 }; 12980 bottomSnippetsBlocksPage.Add(MasterBlockId.MasterReferences, primaryBottomSnippets); 12981 12982 if (Dynamicweb.Rapido.Services.User.IsBuyingAllowed()) 12983 { 12984 Block miniCartPageId = new Block 12985 { 12986 Id = "MiniCartPageId", 12987 Template = RenderMiniCartPageId() 12988 }; 12989 bottomSnippetsBlocksPage.Add(MasterBlockId.MasterReferences, miniCartPageId); 12990 } 12991 12992 ItemViewModel sommifySettings = PageView.Current().AreaSettings.GetItem("Custom").GetItem("SommifySettings"); 12993 if (sommifySettings != null) 12994 { 12995 bool activateSommify = sommifySettings.GetBoolean("ActivateSommify"); 12996 string sommifyApiKey = sommifySettings.GetRawValueString("SommifyApiKey"); 12997 if (activateSommify && !string.IsNullOrEmpty(sommifyApiKey)) 12998 { 12999 Block sommifyData = new Block 13000 { 13001 Id = "SommifyData", 13002 Template = RenderSommifyData(activateSommify, sommifyApiKey, sommifySettings) 13003 }; 13004 bottomSnippetsBlocksPage.Add(MasterBlockId.MasterReferences, sommifyData); 13005 } 13006 } 13007 13008 ItemViewModel internationalTelephoneSettings = PageView.Current().AreaSettings.GetItem("Custom").GetItem("InternationalTelephoneSettings"); 13009 if (internationalTelephoneSettings != null) 13010 { 13011 bool activateInternationalTelephone = internationalTelephoneSettings.GetBoolean("ActivateInternationalTelephone"); 13012 if (activateInternationalTelephone) 13013 { 13014 Block internationalTelephone = new Block 13015 { 13016 Id = "InternationalTelephoneSettings", 13017 Template = RenderInternationalTelephoneSettings(internationalTelephoneSettings) 13018 }; 13019 bottomSnippetsBlocksPage.Add(MasterBlockId.MasterReferences, internationalTelephone); 13020 } 13021 } 13022 13023 string searchType = !string.IsNullOrEmpty(PageView.Current().AreaSettings.GetItem("Layout").GetRawValueString("TopSearch")) ? PageView.Current().AreaSettings.GetItem("Layout").GetRawValueString("TopSearch") : "productSearch"; 13024 if (searchType == "productSearchWithFilters") 13025 { 13026 Block searchFacetsInitializers = new Block 13027 { 13028 Id = "SearchFacetsInitializers", 13029 Template = RenderSearchFacetsInitializers() 13030 }; 13031 bottomSnippetsBlocksPage.Add(MasterBlockId.MasterReferences, searchFacetsInitializers); 13032 } 13033 13034 int activateBooztDiscountPageId = GetPageIdByNavigationTag("ActivateBooztDiscount"); 13035 if (activateBooztDiscountPageId > 0) 13036 { 13037 Block booztDiscountPageId = new Block 13038 { 13039 Id = "BooztDiscountPageId", 13040 Template = RenderActivateBooztDiscountPageId(activateBooztDiscountPageId) 13041 }; 13042 bottomSnippetsBlocksPage.Add(MasterBlockId.MasterReferences, booztDiscountPageId); 13043 } 13044 } 13045 13046 @helper RenderPrimaryBottomSnippets() 13047 { 13048 bool isWireframeMode = Model.Area.Item.GetItem("Settings").GetBoolean("WireframeMode"); 13049 bool useGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetString("GoogleTagManagerID")); 13050 13051 if (isWireframeMode) 13052 { 13053 <script> 13054 Wireframe.Init(true); 13055 </script> 13056 } 13057 13058 //if digitalwarehouse 13059 if (Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("ShowDownloadCart")) 13060 { 13061 string cartContextId = Converter.ToString(HttpContext.Current.Application["DownloadCartContext"]); 13062 13063 if (string.IsNullOrEmpty(cartContextId)) 13064 { 13065 var moduleProps = Dynamicweb.Modules.Properties.GetParagraphModuleSettings(GetPageIdByNavigationTag("DownloadCart"), "eCom_CartV2"); 13066 var cartSettings = new Dynamicweb.Ecommerce.Cart.ModuleSettings(moduleProps); 13067 cartContextId = cartSettings.OrderContextID; 13068 HttpContext.Current.Application["DownloadCartContext"] = cartContextId; 13069 } 13070 13071 <script> 13072 let downloadCart = new DownloadCart({ 13073 cartPageId: @GetPageIdByNavigationTag("MiniCartFeed"), 13074 contextId: "@cartContextId", 13075 addButtonText: "@Translate("Add")", 13076 removeButtonText: "@Translate("Remove")" 13077 }); 13078 </script> 13079 } 13080 13081 <!--$$Javascripts--> 13082 } 13083 13084 @helper RenderMiniCartPageId() 13085 { 13086 int miniCartFeedPageId = GetPageIdByNavigationTag("MiniCartFeed"); 13087 <script> 13088 window.cartId = "@miniCartFeedPageId"; 13089 </script> 13090 } 13091 13092 @helper RenderSommifyData(bool activateSommify, string sommifyApiKey, ItemViewModel sommifySettings) 13093 { 13094 string sommifyPosition = sommifySettings.GetRawValueString("SommifyPosition"); 13095 string sommifyLocalization = sommifySettings.GetRawValueString("SommifyLocalization"); 13096 string sommifyCurrency = sommifySettings.GetRawValueString("SommifyCurrency"); 13097 string sommifySalesWeight = Converter.ToString(sommifySettings.GetInt32("SommifySalesWeight")); 13098 string miniCartFeedPageId = Converter.ToString(GetPageIdByNavigationTag("MiniCartFeed")); 13099 bool sommifyEnableChatFunction = sommifySettings.GetBoolean("SommifyEnableChatFunction"); 13100 bool sommifyEnableFullScreen = sommifySettings.GetBoolean("SommifyEnableFullScreen"); 13101 var sommifyPrompts = sommifySettings.GetItems("SommifyPrompts"); 13102 Dictionary<string, List<string>> sommifyPromptsDictionary = new Dictionary<string, List<string>>(); 13103 13104 if (sommifyPrompts != null && sommifyPrompts.Any()) 13105 { 13106 var prompts = new List<string>(); 13107 foreach (var sommifyPrompt in sommifyPrompts) 13108 { 13109 prompts.Add(sommifyPrompt.GetRawValueString("Prompt")); 13110 } 13111 sommifyPromptsDictionary.Add(sommifyLocalization, prompts); 13112 } 13113 13114 string serializedPrompts = Newtonsoft.Json.JsonConvert.SerializeObject(sommifyPromptsDictionary); 13115 var sommifyConfig = new SommifyConfig(); 13116 sommifyConfig.ApiKey = sommifyApiKey; 13117 sommifyConfig.Position = sommifyPosition; 13118 sommifyConfig.Localization = sommifyLocalization; 13119 sommifyConfig.Currency = sommifyCurrency; 13120 sommifyConfig.SalesWeight = sommifySalesWeight; 13121 sommifyConfig.MiniCartFeedPageId = miniCartFeedPageId; 13122 sommifyConfig.EnableChatFunction = sommifyEnableChatFunction; 13123 sommifyConfig.EnableFullScreen = sommifyEnableFullScreen; 13124 sommifyConfig.Prompts = sommifyPromptsDictionary; 13125 13126 bool useGoogleTagManager = !string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Settings").GetRawValueString("GoogleTagManagerID")); 13127 if (useGoogleTagManager) 13128 { 13129 var user = Dynamicweb.Security.UserManagement.User.GetCurrentExtranetUser(); 13130 var googleImpression = new GoogleImpression() 13131 { 13132 Email = user != null ? user.Email : "", 13133 Guid = Guid.NewGuid().ToString("N"), 13134 ShopId = Pageview.Area.EcomShopId, 13135 AreaId = Converter.ToString(Pageview.AreaID), 13136 Origin = Translate("Sommify.Datalayer.AddToCart.Origin", "Sommify"), 13137 Device = Pageview.Device.ToString() 13138 }; 13139 sommifyConfig.GoogleImpression = Newtonsoft.Json.JsonConvert.SerializeObject(googleImpression); 13140 } 13141 13142 <div class="d-none js-sommify-config" data-config="@HttpUtility.HtmlAttributeEncode(Newtonsoft.Json.JsonConvert.SerializeObject(sommifyConfig))"></div> 13143 } 13144 13145 @helper RenderInternationalTelephoneSettings(ItemViewModel internationalTelephoneSettings) 13146 { 13147 string utilsJsUrl = internationalTelephoneSettings.GetRawValueString("UtilsJsUrl"); 13148 if (!string.IsNullOrEmpty(utilsJsUrl)) 13149 { 13150 string initialCountry = internationalTelephoneSettings.GetRawValueString("InitialCountry"); 13151 bool strictMode = internationalTelephoneSettings.GetBoolean("StrictMode"); 13152 var internationalTelephoneConfig = new InternationalTelephoneConfig(); 13153 internationalTelephoneConfig.UtilsJsUrl = utilsJsUrl; 13154 internationalTelephoneConfig.InitialCountry = initialCountry; 13155 internationalTelephoneConfig.SelectedCountryAriaLabel = Translate("International.Telephone.Input.SelectedCountry", "Valgt land"); 13156 internationalTelephoneConfig.NoCountrySelected = Translate("International.Telephone.Input.NoCountrySelected", "Du har ikke valgt et land"); 13157 internationalTelephoneConfig.CountryListAriaLabel = Translate("International.Telephone.Input.CountryList", "Liste over lande"); 13158 internationalTelephoneConfig.SearchPlaceholder = Translate("International.Telephone.Input.SearchPlaceholder", "Søg"); 13159 internationalTelephoneConfig.ZeroSearchResults = Translate("International.Telephone.Input.NoSearchResults", "Ingen resultater"); 13160 internationalTelephoneConfig.ErrorMessageIsPossible = Translate("International.Telephone.ErrorMessage.IsPossible", "Nummeret er muligt"); 13161 internationalTelephoneConfig.ErrorMessageInvalidCountryCode = Translate("International.Telephone.ErrorMessage.InvalidCountryCode", "Fejlagtig landekode"); 13162 internationalTelephoneConfig.ErrorMessageTooShort = Translate("International.Telephone.ErrorMessage.TooShort", "Nummeret er for kort"); 13163 internationalTelephoneConfig.ErrorMessageTooLong = Translate("International.Telephone.ErrorMessage.TooLong", "Nummeret er for langt"); 13164 internationalTelephoneConfig.ErrorMessageIsPossibleLocalOnly = Translate("International.Telephone.ErrorMessage.IsPossibleLocalOnly", "Nummeret er kun muligt lokalt"); 13165 internationalTelephoneConfig.ErrorMessageInvalidLength = Translate("International.Telephone.ErrorMessage.InvalidLength", "Ugyldig længde"); 13166 internationalTelephoneConfig.StrictMode = strictMode; 13167 13168 <div class="d-none js-international-telephone-config" data-config="@HttpUtility.HtmlAttributeEncode(Newtonsoft.Json.JsonConvert.SerializeObject(internationalTelephoneConfig))"></div> 13169 } 13170 } 13171 13172 @helper RenderSearchFacetsInitializers() 13173 { 13174 <script> 13175 document.addEventListener("DOMContentLoaded", function (event) { 13176 var productSearchBarContent = document.getElementById("ProductSearchBarContent"); 13177 if (productSearchBarContent != null) { 13178 productSearchBarContent.addEventListener('contentLoaded', function (e) { 13179 if (getTarget(e).id === "ProductSearchBarContent") { 13180 Facets.Init("selectedFacets", "ProductSearchBarContent"); 13181 } 13182 }, false); 13183 } 13184 }); 13185 </script> 13186 } 13187 13188 @helper RenderActivateBooztDiscountPageId(int activateBooztDiscountPageId) 13189 { 13190 <script> 13191 window.booztDiscountPageId = "@activateBooztDiscountPageId"; 13192 </script> 13193 } 13194 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 13195 @using System.Web 13196 @using Dynamicweb.Rapido.Blocks.Extensibility 13197 @using Dynamicweb.Rapido.Blocks 13198 @using Dynamicweb 13199 @using Dynamicweb.Core 13200 @using Dynamicweb.Security.UserManagement 13201 @using Smartpage.PhilipsonWine.EcomDiscount.Services 13202 13203 @functions { 13204 public class StockMessage 13205 { 13206 public string Class { get; set; } 13207 public string HeaderMessage { get; set; } 13208 public string BodyMessage { get; set; } 13209 } 13210 string GetHrefLang(string cultureName) 13211 { 13212 var hrefLang = cultureName; 13213 switch (cultureName.ToLower()) 13214 { 13215 case "en-150": 13216 hrefLang = "en-GB"; 13217 break; 13218 } 13219 return hrefLang; 13220 } 13221 13222 string GetProductFieldValue(string productField) 13223 { 13224 var product = Dynamicweb.Ecommerce.Services.Products.GetProductById(Dynamicweb.Context.Current.Request["ProductId"], string.Empty, Dynamicweb.Ecommerce.Common.Context.LanguageID); 13225 if (product != null) 13226 { 13227 string productFieldValue = Converter.ToString(Dynamicweb.Ecommerce.Services.Products.GetProductFieldValue(product, productField)); 13228 if (!string.IsNullOrEmpty(productFieldValue)) 13229 { 13230 return productFieldValue; 13231 } 13232 else 13233 { 13234 return null; 13235 } 13236 } 13237 else 13238 { 13239 return null; 13240 } 13241 } 13242 } 13243 13244 @{ 13245 BlocksPage masterCustomBlocksPage = BlocksPage.GetBlockPage("Master"); 13246 } 13247 13248 @{ 13249 13250 bool userIsImpersonating = Smartpage.PhilipsonWine.Ecommerce.Helpers.Helper.AllowsPartialPurchase(); 13251 Block stockLevelWarningModal = new Block() 13252 { 13253 Id = "stockLevelWarningModal", 13254 SortId = 20, 13255 SkipRenderBlocksList = true, 13256 Template = RenderStockLevelWarningModal(userIsImpersonating) 13257 }; 13258 masterCustomBlocksPage.Add("MasterTopSnippets", stockLevelWarningModal); 13259 13260 13261 bool strictModeForProductAmountSelection = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetBoolean("StrictModeForProductAmountSelection"); 13262 if (strictModeForProductAmountSelection) 13263 { 13264 Block invalidProductAmountModal = new Block() 13265 { 13266 Id = "invalidProductAmountModal", 13267 SortId = 20, 13268 SkipRenderBlocksList = true, 13269 Template = RenderInvalidProductAmountModal(userIsImpersonating) 13270 }; 13271 masterCustomBlocksPage.Add("MasterTopSnippets", invalidProductAmountModal); 13272 } 13273 13274 string userAgent = Dynamicweb.Context.Current.Request.Headers["User-Agent"]; 13275 bool activateAgeRestriction = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetBoolean("ActivateAgeRestriction"); 13276 13277 if (activateAgeRestriction && Dynamicweb.Frontend.PageView.Current().Device != Dynamicweb.Frontend.Devices.DeviceType.Bot) 13278 { 13279 Block ageModalBlock = new Block 13280 { 13281 Id = "AgeModal", 13282 Template = RenderAgeRestrictionModal() 13283 }; 13284 13285 masterCustomBlocksPage.Add(MasterBlockId.MasterHeader, ageModalBlock); 13286 } 13287 13288 Dynamicweb.Security.UserManagement.User frontendUser = Dynamicweb.Security.UserManagement.User.GetCurrentFrontendUser(); 13289 Block engrosRedirectModalBlock = new Block 13290 { 13291 Id = "EngrosRedirectModal", 13292 Template = RenderEngrosRedirectModal(frontendUser) 13293 }; 13294 13295 if (!Converter.ToBoolean(Pageview.AreaSettings.GetItem("Custom").GetBoolean("IsEngrosSite")) && frontendUser != null && Converter.ToBoolean(Dynamicweb.Context.Current.Session["twoday:EngrosRedirect"])) 13296 { 13297 masterCustomBlocksPage.Add(MasterBlockId.MasterHeader, engrosRedirectModalBlock); 13298 13299 Dynamicweb.Context.Current.Session.Remove("twoday:EngrosRedirect"); 13300 } 13301 13302 Block swedishCurrencySelectorBlock = new Block 13303 { 13304 Id = "SwedishCurrencySelector", 13305 Template = RenderSwedishCurrencySelector() 13306 }; 13307 13308 Block businessContactImpersonationModal = new Block 13309 { 13310 Id = "BusinessContactImpersonationModal", 13311 Template = RenderBusinessContactImpersonationModal() 13312 }; 13313 13314 string mainSalesCategory = GetProductFieldValue("SpMainSalesCategory"); 13315 if (!string.IsNullOrEmpty(mainSalesCategory)) 13316 { 13317 string cocktailPackCategory = Dynamicweb.Configuration.SystemConfiguration.Instance.GetValue("/Globalsettings/Smartpage/Ecommerce/CocktailPackCategory"); 13318 if (mainSalesCategory == cocktailPackCategory) 13319 { 13320 Block shareUrlModal = new Block() 13321 { 13322 Id = "shareUrlModal", 13323 Template = RenderShareUrlModal() 13324 }; 13325 masterCustomBlocksPage.Add("MasterTopSnippets", shareUrlModal); 13326 } 13327 } 13328 13329 bool showModalCurrencySelectorModal = Converter.ToBoolean(Dynamicweb.Context.Current.Session["smartpage:SwedishCurrencySelector"]); 13330 13331 if (showModalCurrencySelectorModal) 13332 { 13333 masterCustomBlocksPage.Add(MasterBlockId.MasterHeader, swedishCurrencySelectorBlock); 13334 13335 // Reset session until next time user logs in 13336 Dynamicweb.Context.Current.Session.Remove("smartpage:SwedishCurrencySelector"); 13337 } 13338 13339 bool confirmUserInformationModalActive = Dynamicweb.Configuration.SystemConfiguration.Instance.GetBoolean("/Globalsettings/Smartpage/Customers/ConfirmUserInformationModalActive"); 13340 if (confirmUserInformationModalActive && Pageview.User != null && !showModalCurrencySelectorModal) 13341 { 13342 var customerTypeField = Pageview.User.CustomFieldValues.FirstOrDefault(x => x.CustomField.SystemName == "AccessUser_SpBcCustomerType"); 13343 if (customerTypeField != null && Converter.ToString(customerTypeField.Value).Equals("Private", StringComparison.InvariantCultureIgnoreCase)) 13344 { 13345 var profileUpdatedManuallyDateField = Pageview.User.CustomFieldValues.FirstOrDefault(x => x.CustomField.SystemName == "AccessUser_SpProfileUpdatedManuallyDate"); 13346 if (profileUpdatedManuallyDateField != null) 13347 { 13348 DateTime profileUpdatedManuallyDate = Converter.ToDateTime(profileUpdatedManuallyDateField.Value); 13349 var confirmUserInformationInterval = Dynamicweb.Configuration.SystemConfiguration.Instance.GetInt32("/Globalsettings/Smartpage/Customers/ConfirmUserInformationInterval"); 13350 if (profileUpdatedManuallyDate.AddMonths(confirmUserInformationInterval) < DateTime.Now) 13351 { 13352 Block userEditModalBlock = new Block 13353 { 13354 Id = "UserEditModal", 13355 Template = RenderUserEditModal() 13356 }; 13357 masterCustomBlocksPage.Add(MasterBlockId.MasterHeader, userEditModalBlock); 13358 } 13359 } 13360 } 13361 } 13362 13363 bool showModalBusinessContactImpersonation = Converter.ToBoolean(Dynamicweb.Context.Current.Session["Smartpage:BusinessContactImpersonation"]); 13364 13365 if (showModalBusinessContactImpersonation && GetPageIdByNavigationTag("SignInPage") != Pageview.ID) 13366 { 13367 masterCustomBlocksPage.Add(MasterBlockId.MasterHeader, businessContactImpersonationModal); 13368 13369 // Reset session until next time user logs in 13370 Dynamicweb.Context.Current.Session.Remove("Smartpage:BusinessContactImpersonation"); 13371 } 13372 13373 Block primeurWineAlert = new Block 13374 { 13375 Id = "PrimeurWineAlert", 13376 Template = RenderPrimeurWineAlert() 13377 }; 13378 13379 masterCustomBlocksPage.Add(MasterBlockId.MasterHeader, primeurWineAlert); 13380 13381 Block cartLineNotAddedModal = new Block 13382 { 13383 Id = "CartLineNotAdded", 13384 Template = RenderCartLineNotAddedModal() 13385 }; 13386 13387 masterCustomBlocksPage.Add(MasterBlockId.MasterHeader, cartLineNotAddedModal); 13388 13389 Block hrefLangBlock = new Block 13390 { 13391 Id = "HrefLangBlock", 13392 SortId = 50, 13393 Template = RenderHrefLang() 13394 }; 13395 13396 masterCustomBlocksPage.Add("Head", hrefLangBlock); 13397 13398 string activeCampaignForm = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetString("ActiveCampaignForm"); 13399 if (!string.IsNullOrEmpty(activeCampaignForm) && Dynamicweb.Frontend.PageView.Current().ID == GetPageIdByNavigationTag("LiveshoppingPage")) 13400 { 13401 Block liveshoppingActiveCampaignSignUpModalBlock = new Block 13402 { 13403 Id = "LiveshoppingActiveCampaignSignUpModal", 13404 Template = RenderLiveshoppingActiveCampaignSignUpModal(activeCampaignForm) 13405 }; 13406 13407 masterCustomBlocksPage.Add(MasterBlockId.MasterHeader, liveshoppingActiveCampaignSignUpModalBlock); 13408 } 13409 13410 13411 if (BooztDiscountService.AnyBooztDiscountActivatedForProductPage()) 13412 { 13413 foreach (var booztDiscount in BooztDiscountService.GetDiscounts(Dynamicweb.Security.UserManagement.User.GetCurrentFrontendUser())) 13414 { 13415 Block booztDiscountTermsConditionsModal = new Block 13416 { 13417 Id = "BooztDiscountTermsConditionsModal", 13418 Template = RenderBooztDiscountTermsConditionsModal(booztDiscount) 13419 }; 13420 masterCustomBlocksPage.Add(MasterBlockId.MasterHeader, booztDiscountTermsConditionsModal); 13421 } 13422 } 13423 } 13424 13425 @helper RenderPrimeurWineAlert() 13426 { 13427 <input type="checkbox" id="PrimeurWineModalTrigger" class="modal-trigger"> 13428 <div class="modal-container"> 13429 <label for="PrimeurWineModalTrigger" id="PrimeurWineModalOverlay" class="modal-overlay"></label> 13430 <div class="modal modal--md modal-height--auto" id="rateProductModal"> 13431 <div class="modal__header u-ta-center"> 13432 @Translate("Smartpage:Checkout.Primeur.Alert.Header", "Du kan desværre ikke bestille både en primeur vin og en almindelig vin") 13433 </div> 13434 <div class="modal__body u-ta-center"> 13435 <p>@Translate("Smartpage:Checkout.Primeur.Alert.Text", "Du bedes fjerne enten primeur vinen eller den almindelige")</p> 13436 </div> 13437 <label class="modal__close-btn" for="PrimeurWineModalTrigger"></label> 13438 </div> 13439 </div> 13440 } 13441 13442 @helper RenderStockLevelWarningModal(bool userIsImpersonating) 13443 { 13444 var messages = new List<StockMessage>(); 13445 messages.Add(new StockMessage() 13446 { 13447 Class = "js-out-of-stock-message", 13448 HeaderMessage = Translate("Smartpage:StockLevel.Warning.Header", "Vi har desværre ikke flere på lager"), 13449 BodyMessage = Translate("Smartpage:StockLevel.Warning.Body", "Vi har nedskrevet antal til max lagerantal:") 13450 }); 13451 messages.Add(new StockMessage() 13452 { 13453 Class = "js-max-order-quantity-message", 13454 HeaderMessage = Translate("Smartpage:MaxOrderQuantity.Warning.Header", "Maksimalt ordre antal overskredet"), 13455 BodyMessage = Translate("Smartpage:MaxOrderQuantity.Warning.Body", "Du har overskrevet det maksimalt tilladte antal:") 13456 }); 13457 if (userIsImpersonating) 13458 { 13459 messages.Add(new StockMessage() 13460 { 13461 Class = "js-impersonator-max-order-quantity-message", 13462 HeaderMessage = Translate("Smartpage:Impersonator.MaxOrderQuantity.Warning.Header", "Maksimalt ordre antal overskredet"), 13463 BodyMessage = Translate("Smartpage:Impersonator.MaxOrderQuantity.Warning.Body", "Vær opmærksom på, at du har overskrevet det maksimalt tilladte antal.<br><b>Da du er impersonator har du dog lov til det.</b> Det maksimale tilladte antal er:") 13464 }); 13465 } 13466 <input type="checkbox" id="stockLevelWarningModalTrigger" class="modal-trigger"> 13467 <div class="modal-container"> 13468 <label for="stockLevelWarningModalTrigger" id="stockLevelWarningModalOverlay" class="modal-overlay"></label> 13469 <div class="modal modal-height--auto js-stock-level-warning-modal @(userIsImpersonating ? "js-user-is-impersonator" : "")"> 13470 @foreach (var message in messages) 13471 { 13472 <div class="js-message @message.Class"> 13473 <div class="modal__header">@message.HeaderMessage</div> 13474 <div class="modal__body">@message.BodyMessage <span class="js-modal__max"></span></div> 13475 </div> 13476 } 13477 <label class="modal__close-btn" for="stockLevelWarningModalTrigger"></label> 13478 </div> 13479 </div> 13480 } 13481 13482 @helper RenderInvalidProductAmountModal(bool userIsImpersonator) 13483 { 13484 var messages = new List<StockMessage>(); 13485 messages.Add(new StockMessage() 13486 { 13487 Class = "js-invalid-amount-message", 13488 HeaderMessage = Translate("Smartpage:InvalidAmount.Warning.Header", "Antallet er ugyldigt"), 13489 BodyMessage = Translate("Smartpage:InvalidAmount.Warning.Body", "Du bedes købe varen i hele kasser.<br>Det nærmeste gyldige antal er:") 13490 }); 13491 messages.Add(new StockMessage() 13492 { 13493 Class = "js-invalid-amount-already-in-cart-message", 13494 HeaderMessage = Translate("Smartpage:InvalidAmount.AlreadyInCart.Warning.Header", "Du bedes købe varen i hele kasser"), 13495 BodyMessage = Translate("Smartpage:InvalidAmount.AlreadyInCart.Warning.Body", "Du har allerede varen i kurven, og det samlede antal er ugyldigt.<br>Det <b>nærmeste gyldige antal</b> du yderligere kan tilføje er:") 13496 }); 13497 messages.Add(new StockMessage() 13498 { 13499 Class = "js-in-cart-invalid-amount-message", 13500 HeaderMessage = Translate("Smartpage:InvalidAmount.ChangeCart.Warning.Header", "Antallet er ugyldigt"), 13501 BodyMessage = Translate("Smartpage:InvalidAmount.ChangeCart.Warning.Body", "Du bedes købe varen i hele kasser.<br>Du kan i stedet ændre antallet til det nærmeste gyldige antal:") 13502 }); 13503 if (userIsImpersonator) 13504 { 13505 messages.Add(new StockMessage() 13506 { 13507 Class = "js-impersonator-invalid-amount-message", 13508 HeaderMessage = Translate("Smartpage:InvalidAmount.Impersonator.Warning.Header", "Antallet bryder varens kolli tal"), 13509 BodyMessage = Translate("Smartpage:InvalidAmount.Impersonator.Warning.Body", "Vær opmærksom på, at det samlede antal bryder varens kolli.<br>Det er tilladt da du er impersonator, men du kan evt. opdatere til dette nærmeste gyldige antal:") 13510 }); 13511 } 13512 bool isCartPage = Pageview.ID == GetPageIdByNavigationTag("CartPage"); 13513 13514 <input type="checkbox" id="invalidProductAmountWarningModalTrigger" class="modal-trigger"> 13515 <div class="modal-container"> 13516 <label for="invalidProductAmountWarningModalTrigger" id="invalidProductAmountWarningModalOverlay" class="modal-overlay @(isCartPage ? "js-in-cart-invalid-amount-prevent-close" : "")"></label> 13517 <div class="modal modal-height--auto js-invalid-product-amount-warning-modal @(userIsImpersonator ? "js-product-amount-impersonator-mode" : "js-product-amount-strict-mode")"> 13518 @foreach (var message in messages) 13519 { 13520 <div class="js-message @message.Class"> 13521 <div class="modal__header">@message.HeaderMessage</div> 13522 <div class="modal__body">@message.BodyMessage <b class="js-modal__nearest-valid-amount"></b><span class="js-modal__total-product-amount-container">@Translate("Smartpage.InvalidAmount.Warning.TotalAmount", "<br>Det <b>samlede antal i din kurv</b> vil i alt være:") <b class="js-modal__total-product-amount"></b></span></div> 13523 <div class="d-none js-in-cart-invalid-amount-button-container in-cart-invalid-amount-button-container"> 13524 @if (userIsImpersonator) 13525 { 13526 <label class="btn btn--secondary dw-mod js-in-cart-impersonator-invalid-amount-close-modal" for="invalidProductAmountWarningModalTrigger" style="">@Translate("Smartpage:InvalidAmount.Impersonator.ChangeCart.Warning.Decline", "Nej tak, behold mit valg")</label> 13527 } 13528 else 13529 { 13530 <div class="btn btn--secondary dw-mod js-in-cart-invalid-amount-decline-nearest" style="">@Translate("Smartpage:InvalidAmount.ChangeCart.Warning.Decline", "Nej tak, behold tidligere antal")</div> 13531 } 13532 <div class="btn btn--primary dw-mod js-in-cart-invalid-amount-accept-nearest" style="">@Translate("Smartpage:InvalidAmount.ChangeCart.Warning.Accept", "Ja tak, opdatér antal")</div> 13533 </div> 13534 </div> 13535 } 13536 <label class="modal__close-btn @(isCartPage ? "js-in-cart-invalid-amount-prevent-close-btn" : "")" for="invalidProductAmountWarningModalTrigger"></label> 13537 </div> 13538 </div> 13539 } 13540 13541 @helper RenderMobileTopSearchBar() 13542 { 13543 string searchFeedId = ""; 13544 string searchSecondFeedId = ""; 13545 int groupsFeedId; 13546 string productsSearchId = Converter.ToString(GetPageIdByNavigationTag("ProductSearchFeed")); 13547 int productsPageId = GetPageIdByNavigationTag("ProductsPage"); 13548 string contentSearchPageLink = GetPageIdByNavigationTag("ContentSearchResults") + "&Areaid=" + Model.Area.ID; 13549 string resultPageLink; 13550 string searchPlaceholder; 13551 string searchType = "product-search"; 13552 string searchTemplate; 13553 string searchContentTemplate = ""; 13554 string searchValue = HttpContext.Current.Request.QueryString.Get("Search") ?? ""; 13555 bool showGroups = true; 13556 13557 if (Model.Area.Item.GetItem("Layout").GetList("TopSearch").SelectedValue == "contentSearch") 13558 { 13559 searchFeedId = GetPageIdByNavigationTag("ContentSearchFeed") + "&Areaid=" + Model.Area.ID + "&pagesOnly=true"; 13560 resultPageLink = contentSearchPageLink; 13561 searchPlaceholder = Translate("Search page"); 13562 groupsFeedId = 0; 13563 searchType = "content-search"; 13564 searchTemplate = "SearchPagesTemplate"; 13565 showGroups = false; 13566 } 13567 else if (Model.Area.Item.GetItem("Layout").GetList("TopSearch").SelectedValue == "combinedSearch") 13568 { 13569 searchFeedId = productsPageId + "&feed=true"; 13570 searchSecondFeedId = GetPageIdByNavigationTag("ContentSearchFeed") + "&Areaid=" + Model.Area.ID + "&pagesOnly=true"; 13571 resultPageLink = Converter.ToString(productsPageId); 13572 searchPlaceholder = Translate("Search products or pages"); 13573 groupsFeedId = GetPageIdByNavigationTag("ProductGroupsFeed"); 13574 searchType = "combined-search"; 13575 searchTemplate = "SearchProductsTemplateWrap"; 13576 searchContentTemplate = "SearchPagesTemplateWrap"; 13577 showGroups = Model.Area.Item.GetItem("Layout").GetBoolean("ShowGroupsSelector"); 13578 } 13579 else 13580 { 13581 resultPageLink = Converter.ToString(productsPageId); 13582 searchFeedId = productsSearchId + "&feed=true"; 13583 groupsFeedId = GetPageIdByNavigationTag("ProductGroupsFeed"); 13584 searchPlaceholder = Translate("Search products"); 13585 searchTemplate = "SearchResultsTypeAheadMobile"; 13586 searchType = "product-search"; 13587 showGroups = Model.Area.Item.GetItem("Layout").GetBoolean("ShowGroupsSelector"); 13588 } 13589 13590 <input type="checkbox" id="MobileSearchTrigger" class="mobile-search-trigger" /> 13591 13592 <div class="main-navigation-mobile typeahead-mobile dw-mod"> 13593 <div class="center-container top-container__center-container u-no-padding dw-mod"> 13594 <div class="grid"> 13595 <div class="grid__col-auto"> 13596 <div class="typeahead-mobile__search-field dw-mod u-no-padding-x js-typeahead" data-page-size="@(searchType == "combined-search" ? 4 : 8)" id="MobileProductSearch" data-search-feed-id="@searchFeedId" data-search-second-feed-id="@searchSecondFeedId" data-result-page-id="@resultPageLink" data-search-type="@searchType"> 13597 <form action="@Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(GetPageIdByNavigationTag("ProductsPage"))"> 13598 <input id="TypeaheadSearchFieldMobile" type="text" class="js-typeahead-search-field u-w160px u-no-margin" placeholder="@HttpUtility.HtmlAttributeEncode(searchPlaceholder)" value="@HttpUtility.HtmlAttributeEncode(searchValue)" name="Search" data-shop-id="@Pageview.Area.EcomShopId" data-area-id="@Converter.ToString(Pageview.AreaID)"> 13599 </form> 13600 @if (string.IsNullOrEmpty(searchSecondFeedId)) 13601 { 13602 <ul class="dropdown dropdown--absolute-position u-min-w220px u-full-width js-handlebars-root js-typeahead-search-content dw-mod" id="MobileProductSearchBarContent" data-template="@searchTemplate" data-json-feed="/Default.aspx?ID=@searchFeedId&feedType=productsOnly" data-init-onload="false"></ul> 13603 } 13604 else 13605 { 13606 <div class="dropdown dropdown--absolute-position dropdown--combined grid dropdown--combined-mobile grid"> 13607 13608 <div class="js-handlebars-root js-typeahead-search-content grid__col-sm-7 grid__col--bleed-y" id="MobileProductSearchBarContent" data-template="@searchTemplate" data-json-feed="/Default.aspx?ID=@searchFeedId&feedType=productsOnly" data-init-onload="false"></div> 13609 <div class="js-handlebars-root js-typeahead-additional-search-content grid__col-sm-5 grid__col--bleed-y" id="MobileContentSearchBarContent" data-template="@searchContentTemplate" data-json-feed="/Default.aspx?ID=@searchSecondFeedId" data-init-onload="false"></div> 13610 <div class="js-spell-check-suggestions grid__col-sm-12 grid__col--bleed-y" id="SpellCheckerSuggestionsSearchBarContent" data-template="SearchSpellCheckerSuggestionsTemplateWrap" data-init-onload="false"></div> 13611 </div> 13612 } 13613 <button type="button" class="btn btn--condensed btn--primary u-no-margin dw-mod js-typeahead-enter-btn"><i class="@Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetList("SearchIcon").SelectedValue"></i></button> 13614 </div> 13615 </div> 13616 </div> 13617 </div> 13618 </div> 13619 } 13620 13621 @helper RenderEngrosRedirectModal(Dynamicweb.Security.UserManagement.User frontendUser) 13622 { 13623 string logo = Model.Area.Item.GetItem("Layout").GetFile("LogoImage") != null ? Model.Area.Item.GetItem("Layout").GetFile("LogoImage").PathUrlEncoded : "/Files/Images/logo-dynamicweb.png"; 13624 if (Path.GetExtension(logo).ToLower() != ".svg") 13625 { 13626 int logoHeight = Model.Area.Item.GetItem("Layout").GetInt32("LogoHeight"); 13627 logoHeight = logoHeight > 0 && Pageview.Device != Dynamicweb.Frontend.Devices.DeviceType.Mobile ? logoHeight : 40; 13628 logo = "/Admin/Public/GetImage.ashx?height=" + Converter.ToString(logoHeight) + "&amp;crop=5&amp;Compression=75&amp;image=" + logo; 13629 } 13630 else 13631 { 13632 logo = HttpUtility.UrlDecode(logo); 13633 } 13634 13635 var redirect = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetRawValueString("EngrosRedirectUrl"); 13636 if (frontendUser != null) 13637 { 13638 string userName = frontendUser.UserName; 13639 string userPassword = frontendUser.Password; 13640 if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(userPassword)) 13641 { 13642 string loginToken = Dynamicweb.Frontend.LoginHandler.GetLoginToken(userName, userPassword); 13643 if (!string.IsNullOrEmpty(loginToken)) 13644 { 13645 redirect += "?username=" + userName + "&PwToken=" + loginToken; 13646 } 13647 } 13648 } 13649 13650 <input type="checkbox" id="EngrosRedirectModalTrigger" class="modal-trigger" checked> 13651 <div class="modal-container"> 13652 <label class="modal-overlay model-overlay--disallow"></label> 13653 <div class="modal modal--md modal-height--auto engros-redirect-modal" id="EngrosRedirectModal"> 13654 <div class="modal__header"> 13655 <img class="grid__cell-img logo__img dw-mod" src="@logo" alt="Logo"> 13656 <div class="u-ta-center header-text"> 13657 <strong>@Translate("Smartpage:EngrosRedirectModal.Welcome", "Velkommen tilbage")</strong> 13658 </div> 13659 </div> 13660 <div class="modal__body"> 13661 <div class="u-ta-center">@Translate("Smartpage:EngrosRedirectModal.Text", "Vi kan se at du har brugeradgang til vores professionel site.")</div> 13662 <div class="u-ta-center focus-text">@Translate("Smartpage:EngrosRedirectModal.FocusText", "Videre til professionel site?")</div> 13663 <div class="engros-redirect-modal__buttons"> 13664 <label for="EngrosRedirectModalTrigger" class="btn btn--secondary dw-mod">@Translate("Smartpage:EngrosRedirectModal.No", "Nej, bliv her")</label> 13665 <a href="@redirect" class="btn btn--primary dw-mod" onclick="">@Translate("Smartpage:EngrosRedirectModal.Yes", "Ja, videre tak")</a> 13666 </div> 13667 </div> 13668 </div> 13669 </div> 13670 } 13671 13672 @helper RenderAgeRestrictionModal() 13673 { 13674 string logo = Model.Area.Item.GetItem("Layout").GetFile("LogoImage") != null ? Model.Area.Item.GetItem("Layout").GetFile("LogoImage").PathUrlEncoded : "/Files/Images/logo-dynamicweb.png"; 13675 if (Path.GetExtension(logo).ToLower() != ".svg") 13676 { 13677 int logoHeight = Model.Area.Item.GetItem("Layout").GetInt32("LogoHeight"); 13678 logoHeight = logoHeight > 0 && Pageview.Device.ToString() != "Mobile" ? logoHeight : 40; 13679 logo = "/Admin/Public/GetImage.ashx?height=" + Converter.ToString(logoHeight) + "&amp;crop=5&amp;Compression=75&amp;image=" + logo; 13680 } 13681 else 13682 { 13683 logo = HttpUtility.UrlDecode(logo); 13684 } 13685 13686 <input type="checkbox" id="AgeRestrictionModalTrigger" class="modal-trigger"> 13687 <div class="modal-container"> 13688 <label class="modal-overlay model-overlay--disallow"></label> 13689 <div class="modal modal--md modal-height--auto age-restriction-modal" id="AgeRestrictionModal"> 13690 <div class="modal__header"> 13691 <img class="grid__cell-img logo__img dw-mod" src="@logo" alt="Logo"> 13692 <div class="u-ta-center header-text"> 13693 <strong>@Translate("Smartpage:AgeRestrictionModal.Welcome", "Velkommen")</strong> 13694 </div> 13695 </div> 13696 <div class="modal__body"> 13697 <div class="u-ta-center">@Translate("Smartpage:AgeRestrictionModal.Text", "Husk at du skal være fyldt 18 år for at købe varer indeholdende alkohol hos PhilipsonWine.com")</div> 13698 <div class="u-ta-center focus-text">@Translate("Smartpage:AgeRestrictionModal.AreYouOverEighteen", "Er du over 18 år?")</div> 13699 <div class="age-restriction-modal__buttons"> 13700 <a href="/Default.aspx?ID=@GetPageIdByNavigationTag("AgeRestrictionPage")" class="btn btn--secondary dw-mod js-decline-age-consent" onclick="setAgeConsent(event, false)">@Translate("Smartpage:AgeRestrictionModal.No", "Nej")</a> 13701 <button class="btn btn--primary dw-mod" onclick="setAgeConsent(event, true)">@Translate("Smartpage:AgeRestrictionModal.Yes", "Ja")</button> 13702 </div> 13703 </div> 13704 </div> 13705 </div> 13706 13707 <script> 13708 // Check if user has taken action on age restriction modal 13709 document.addEventListener("DOMContentLoaded", function () { 13710 var modalTrigger = document.getElementById('AgeRestrictionModalTrigger'); 13711 var expiresIn = localStorage.getItem('OverEighteenInteraction.ExpiresIn'); 13712 var today = new Date(); 13713 if (localStorage.getItem('OverEighteenInteraction') == 'null' || (expiresIn != 'null' && new Date(expiresIn) < today)) { 13714 if (modalTrigger != null) { 13715 modalTrigger.checked = true; 13716 } 13717 // Disallow scroll until user has taken action on age restriction modal 13718 document.querySelector('body').style.height = '100%'; 13719 } 13720 if (localStorage.getItem('OverEighteenInteraction') == 'false' && expiresIn != 'null' && new Date(expiresIn) > today) { 13721 var notAllowedLink = document.querySelector('.js-decline-age-consent').getAttribute('href'); 13722 if (notAllowedLink != null) { 13723 window.location.href = notAllowedLink; 13724 } 13725 } 13726 if (expiresIn != 'null' && new Date(expiresIn) < today && modalTrigger != null) { 13727 modalTrigger.checked = true; 13728 } 13729 }); 13730 13731 function setAgeConsent(event, selection) { 13732 event.preventDefault(); 13733 13734 // Allow scroll again 13735 document.querySelector('body').style.height = 'initial'; 13736 13737 // Hide modal 13738 var modalTrigger = document.getElementById('AgeRestrictionModalTrigger'); 13739 if (modalTrigger != null) { 13740 modalTrigger.checked = true; 13741 } 13742 13743 // Expires in 13744 var oneWeekFromNow = new Date(); 13745 oneWeekFromNow.setDate(oneWeekFromNow.getDate() + 7); 13746 localStorage.setItem('OverEighteenInteraction.ExpiresIn', oneWeekFromNow); 13747 13748 if (selection) { 13749 // Save selection 13750 localStorage.setItem('OverEighteenInteraction', 'true'); 13751 modalTrigger.checked = false; 13752 } else { 13753 localStorage.setItem('OverEighteenInteraction', 'false'); 13754 window.location.href = event.target.getAttribute('href'); 13755 } 13756 } 13757 </script> 13758 } 13759 13760 @helper RenderSwedishCurrencySelector() 13761 { 13762 // Use PageID for navigating user instead of AreaID to avoid infinite triggering of modal 13763 string queryString = Dynamicweb.Environment.Helpers.LinkHelper.StripQueryString(HttpContext.Current.Request.Url.PathAndQuery, "AreaID"); 13764 queryString = Dynamicweb.Environment.Helpers.LinkHelper.StripQueryString(queryString, "CurrencyCode"); 13765 queryString = Dynamicweb.Environment.Helpers.LinkHelper.ReplaceQueryString(queryString, "Id", Converter.ToString(Pageview.ID)); 13766 13767 <input type="checkbox" id="SwedishCurrencySelectorModalTrigger" class="modal-trigger"> 13768 <div class="modal-container"> 13769 <label class="modal-overlay model-overlay--disallow"></label> 13770 <div class="modal modal--lg modal-height--auto swedish-currency-selector-modal" id="SwedishCurrencySelectorModal"> 13771 <div class="modal__header"> 13772 <div class="u-ta-center header-text"> 13773 <strong>@Translate("Smartpage:SwedishCurrencySelector.Welcome", "Velkommen")</strong> 13774 </div> 13775 </div> 13776 <div class="modal__body"> 13777 <div class="grid"> 13778 <div class="grid__col-12 grid__col-sm-6 currency-section"> 13779 <div class="u-ta-center">@Translate("Smartpage:SwedishCurrencySelector.SwedishCurrencyOptionText", "Ønsker du at få din ordre sendt med fragt, da vil ordren blive beregnet i SEK inkl. Svenske afgifter")</div> 13780 <a href="@Dynamicweb.Environment.Helpers.LinkHelper.AddToQueryString(queryString, "CurrencyCode=SEK")" class="btn btn--primary dw-mod">@Translate("Smartpage:SwedishCurrencySelector.SwedishCurrencyOption", "SEK")</a> 13781 </div> 13782 <div class="grid__col-12 grid__col-sm-6 currency-section"> 13783 <div class="u-ta-center">@Translate("Smartpage:SwedishCurrencySelector.DanishCurrencyOptionText", "Ønsker du at afhente din ordre, da vil ordren blive beregnet i DKK")</div> 13784 <a href="@Dynamicweb.Environment.Helpers.LinkHelper.AddToQueryString(queryString, "CurrencyCode=DKK")" class="btn btn--primary dw-mod">@Translate("Smartpage:SwedishCurrencySelector.DanishCurrencyOption", "DKK")</a> 13785 </div> 13786 </div> 13787 </div> 13788 </div> 13789 </div> 13790 13791 <script> 13792 document.addEventListener("DOMContentLoaded", function () { 13793 var modalTrigger = document.getElementById('SwedishCurrencySelectorModalTrigger'); 13794 if (modalTrigger != null) { 13795 modalTrigger.checked = true; 13796 } 13797 }); 13798 </script> 13799 } 13800 13801 @helper CustomRenderMasterMetadata() 13802 { 13803 var swatches = new Dynamicweb.Content.Items.ColorSwatchService(); 13804 var brandColors = swatches.GetColorSwatch(Pageview.AreaID); 13805 string brandColorOne = brandColors.Palette["BrandColor1"]; 13806 13807 if (!String.IsNullOrEmpty(Model.Area.Item.GetItem("Settings").GetString("AppName")) && Model.Area.Item.GetItem("Settings").GetFile("AppIcon") != null) 13808 { 13809 Manifest manifest = new Manifest 13810 { 13811 name = Model.Area.Item.GetItem("Settings").GetString("AppName"), 13812 short_name = !String.IsNullOrEmpty(Model.Area.Item.GetItem("Settings").GetString("AppShortName")) ? Model.Area.Item.GetItem("Settings").GetString("AppShortName") : Model.Area.Item.GetItem("Settings").GetString("AppName"), 13813 start_url = "/", 13814 display = "standalone", 13815 background_color = Model.Area.Item.GetItem("Settings").GetString("AppBackgroundColor"), 13816 theme_color = Model.Area.Item.GetItem("Settings").GetString("AppThemeColor") 13817 }; 13818 13819 manifest.icons = new List<ManifestIcon> { 13820 new ManifestIcon { 13821 src = "/Admin/Public/GetImage.ashx?width=192&height=192&crop=5&image=" + Model.Area.Item.GetItem("Settings").GetFile("AppIcon").PathUrlEncoded, 13822 sizes = "192x192", 13823 type = "image/png" 13824 }, 13825 new ManifestIcon { 13826 src = "/Admin/Public/GetImage.ashx?width=512&height=512&crop=5&image=" + Model.Area.Item.GetItem("Settings").GetFile("AppIcon").PathUrlEncoded, 13827 sizes = "512x512", 13828 type = "image/png" 13829 }, 13830 new ManifestIcon { 13831 src = "/Admin/Public/GetImage.ashx?width=1024&height=1024&crop=5&image=" + Model.Area.Item.GetItem("Settings").GetFile("AppIcon").PathUrlEncoded, 13832 sizes = "1024x1024", 13833 type = "image/png" 13834 } 13835 }; 13836 13837 string manifestFilePath = HttpContext.Current.Request.MapPath("/Files/Templates/Designs/Rapido/manifest.json"); 13838 string manifestJSON = Newtonsoft.Json.JsonConvert.SerializeObject(manifest); 13839 string currentManifest = File.ReadAllText(manifestFilePath); 13840 13841 if (manifestJSON != currentManifest) 13842 { 13843 File.WriteAllText(manifestFilePath, manifestJSON); 13844 } 13845 } 13846 13847 string titleTag = Model.Title; 13848 13849 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["ProductId"])) 13850 { 13851 titleTag = $"{Translate("Smartpage:ProductTitleTag.Buy", "Køb")} {Model.Title.TrimEnd()} {Translate("Smartpage:ProductTitleTag.Today", "i dag")} | {Translate("Smartpage:ProductTitleTag.Name", "Philipson Wine")}"; 13852 } 13853 13854 <meta charset="utf-8" /> 13855 <title>@titleTag</title> 13856 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 13857 <meta name="theme-color" content="@brandColorOne" /> 13858 13859 if (Model.MetaTags != null && !Model.MetaTags.Contains("robots")) 13860 { 13861 Pageview.Meta.AddTag("robots", "index, follow"); 13862 } 13863 13864 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["ProductId"])) 13865 { 13866 if (!string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Custom").GetString("OpenGraphGlobalImage")) && Model.MetaTags != null && !Model.MetaTags.Contains("og:image") && Model.PropertyItem != null && Model.PropertyItem.GetFile("OpenGraphImage") != null) 13867 { 13868 string logoimage = Converter.ToString(Pageview.AreaSettings.GetItem("Custom").GetFile("OpenGraphGlobalImage").Path); 13869 var metaImage = "<meta property=\"og:image\" content=\"" + string.Format("{0}://{1}{2}", Dynamicweb.Context.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Host, logoimage) + "\">"; 13870 Pageview.Meta.AddTag(metaImage); 13871 } 13872 string productUrl = Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl("Default.aspx?Id=" + GetPageIdByNavigationTag("ProductsPage") + "&ProductId=" + Dynamicweb.Context.Current.Request["ProductId"]); 13873 if (!string.IsNullOrEmpty(productUrl)) 13874 { 13875 Pageview.Meta.AddTag("customCan", "<link rel=\"canonical\" href=\"" + Dynamicweb.Context.Current.Request.Url.Scheme + "://" + Dynamicweb.Context.Current.Request.Url.Host + productUrl + "\">"); 13876 } 13877 } 13878 else 13879 { 13880 if (Model.MetaTags != null && !Model.MetaTags.Contains("og:image") && Model.PropertyItem != null && Model.PropertyItem.GetFile("OpenGraphImage") != null) 13881 { 13882 Pageview.Meta.AddTag("og:image", string.Format("{0}://{1}{2}", Dynamicweb.Context.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Host, Model.PropertyItem.GetFile("OpenGraphImage"))); 13883 } 13884 else 13885 { 13886 if (!string.IsNullOrEmpty(Pageview.AreaSettings.GetItem("Custom").GetString("OpenGraphGlobalImage"))) 13887 { 13888 string logoimage = Converter.ToString(Pageview.AreaSettings.GetItem("Custom").GetFile("OpenGraphGlobalImage").Path); 13889 var metaImage = "<meta property=\"og:image\" content=\"" + string.Format("{0}://{1}{2}", Dynamicweb.Context.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Host, logoimage) + "\">"; 13890 Pageview.Meta.AddTag(metaImage); 13891 } 13892 } 13893 } 13894 13895 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["ProductId"])) 13896 { 13897 string description = $"{Translate("Smartpage:ProductDescriptionTag.Buy", "Køb")} {Model.Title.TrimEnd()} {Translate("Smartpage:ProductDescriptionTag.DeliveryText", "og få hurtig levering til din dør med fri fragt ved køb over 399 kroner.")}"; 13898 string producerCode = GetProductFieldValue("SpProducerCode"); 13899 13900 if (!string.IsNullOrEmpty(producerCode)) 13901 { 13902 var producer = Smartpage.PhilipsonWine.Producer.CustomProducerService.Instance.GetProducer(producerCode); 13903 if (producer != null && !string.IsNullOrWhiteSpace(producer.ProducerName)) 13904 { 13905 description = $"{Translate("Smartpage:ProductDescriptionTag.Buy", "Køb")} {Model.Title.TrimEnd()} {Translate("Smartpage:ProductDescriptionTag.From", "fra")} {producer.ProducerName} {Translate("Smartpage:ProductDescriptionTag.DeliveryText", "og få hurtig levering til din dør med fri fragt ved køb over 399 kroner.")}"; 13906 } 13907 } 13908 13909 Pageview.Meta.AddTag("description", HttpUtility.HtmlAttributeEncode(description)); 13910 Pageview.Meta.AddTag("<meta property=\"og:description\" content=\"" + HttpUtility.HtmlAttributeEncode(description) + "\">"); 13911 } 13912 else if (!Model.MetaTags.Contains("og:description") && !string.IsNullOrEmpty(Model.Description)) 13913 { 13914 var description = Regex.Replace(Model.Description, "<.*?>", string.Empty); 13915 var metadescription = "<meta property=\"og:description\" content=\"" + HttpUtility.HtmlAttributeEncode(description) + "\">"; 13916 Pageview.Meta.AddTag(metadescription); 13917 } 13918 13919 Pageview.Meta.AddTag("<meta property=\"og:title\" content=\"" + HttpUtility.HtmlAttributeEncode(titleTag) + "\">"); 13920 13921 Pageview.Meta.AddTag("<meta property=\"og:site_name\" content=\"" + Pageview.Area.Name + "\">"); 13922 Pageview.Meta.AddTag("<meta property=\"og:url\" content=\"" + HttpContext.Current.Request.Url.ToString() + "\">"); 13923 13924 // check to see if the current page is a productpage 13925 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["ProductId"])) 13926 { 13927 Pageview.Meta.AddTag("<meta property=\"og:type\" content=\"Product\">"); 13928 } 13929 else 13930 { 13931 Pageview.Meta.AddTag("<meta property=\"og:type\" content=\"Website\">"); 13932 } 13933 13934 if (!string.IsNullOrEmpty(Model.Area.Item.GetItem("Settings").GetString("FacebookAppID"))) 13935 { 13936 Pageview.Meta.AddTag("fb:app_id", Model.Area.Item.GetItem("Settings").GetString("FacebookAppID")); 13937 } 13938 13939 @Model.MetaTags 13940 } 13941 13942 @helper RenderCartLineNotAddedModal() 13943 { 13944 <input type="checkbox" id="CartLineNotAddedModalTrigger" class="modal-trigger"> 13945 <div class="modal-container"> 13946 <label class="modal-overlay"></label> 13947 <div class="modal modal--lg modal-height--auto" id="CartLineNotAddedModal"> 13948 <div class="modal__header u-fs-18"> 13949 <div class="u-ta-center"> 13950 <strong><span class="js-product-name"></span><span class="u-underline">@Translate("Smartpage:CartLineNotAddedModal.CouldNotBeAdded", " kunne ikke tilføjes til kurven")</span></strong> 13951 </div> 13952 </div> 13953 <div class="modal__body"> 13954 <div class="grid grid--justify-center"> 13955 <div class="grid__col-12 grid__col-sm-6"> 13956 <div class="u-ta-center js-text-description u-margin-bottom"></div> 13957 <div class="u-ta-center js-text-add-quantity-instead u-margin-bottom u-bold"></div> 13958 <div class="grid"> 13959 <div class="grid__col-sm-auto"> 13960 <button class="btn btn--secondary u-no-margin--bottom dw-mod js-dismiss-modal" onclick="document.getElementById('CartLineNotAddedModalTrigger').checked = false;">@Translate("Smartpage:CartLineNotAddedModal.OK", "OK")</button> 13961 </div> 13962 <div class="grid__col-sm-auto u-display-none"> 13963 <button class="btn btn--primary dw-mod u-no-margin--bottom js-add-quantity-instead" onclick="document.getElementById('CartLineNotAddedModalTrigger').checked = false;">@Translate("Smartpage:CartLineNotAddedModal.Add", "Tilføj")</button> 13964 </div> 13965 </div> 13966 </div> 13967 </div> 13968 </div> 13969 <label class="modal__close-btn u-margin-top-5" for="CartLineNotAddedModalTrigger"></label> 13970 </div> 13971 </div> 13972 } 13973 13974 @helper RenderHrefLang() 13975 { 13976 var languages = Model.Languages.Where(l => Dynamicweb.Content.Services.Areas.GetArea(l.ID).Published).ToList(); 13977 foreach (var language in languages) 13978 { 13979 string domain = !string.IsNullOrEmpty(language.PrimaryDomain) ? language.PrimaryDomain : Dynamicweb.Context.Current.Request.Url.Host; 13980 if (!string.IsNullOrEmpty(domain)) 13981 { 13982 var qs = HttpUtility.ParseQueryString(System.Web.HttpContext.Current.Request.QueryString.ToString()); 13983 qs.Set("ID", Convert.ToString(language.Page.ID)); 13984 13985 var page = Dynamicweb.Content.Services.Pages.GetPage(language.FirstActivePage.ID); 13986 13987 string url = domain + Dynamicweb.Frontend.SearchEngineFriendlyURLs.GetFriendlyUrl(language.Page.ID); 13988 13989 foreach (string key in qs) 13990 { 13991 if (key == null || key.Equals("ID", StringComparison.InvariantCultureIgnoreCase)) 13992 { 13993 continue; 13994 } 13995 13996 var urlFromHandler = Dynamicweb.Frontend.UrlProviders.Handler.GetUrlFromQueryString(key, qs[key], page.Area.EcomLanguageId); 13997 if (Dynamicweb.Frontend.SearchEngineFriendlyURLs.UseExtensionLessUrls) 13998 { 13999 url += urlFromHandler.Replace(".aspx", ""); 14000 } 14001 else 14002 { 14003 url = url.Replace(".aspx", urlFromHandler); 14004 } 14005 14006 } 14007 14008 if (url.Contains("/forside")) 14009 { 14010 url = url.Replace("/forside", ""); 14011 } 14012 14013 <link rel="alternate" hreflang="@GetHrefLang(language.Culture)" href="@(Dynamicweb.Context.Current.Request.Url.Scheme + "://" + url)" /> 14014 14015 if (GetHrefLang(language.Culture) == "en-GB") 14016 { 14017 <link rel="alternate" hreflang="x-default" href="@(Dynamicweb.Context.Current.Request.Url.Scheme + "://" + url)" /> 14018 } 14019 } 14020 } 14021 } 14022 14023 @helper RenderLiveshoppingActiveCampaignSignUpModal(string activeCampaignForm) 14024 { 14025 <input type="checkbox" id="LiveshoppingActiveCampaignSignUpModalTrigger" class="modal-trigger"> 14026 <div class="modal-container"> 14027 <label for="LiveshoppingActiveCampaignSignUpModalTrigger" class="modal-overlay"></label> 14028 <div class="modal modal--md modal-height--auto liveshopping-signup-modal" id="LiveshoppingActiveCampaignSignUpModal"> 14029 <div class="modal__header"> 14030 <div class="u-ta-center header-text"> 14031 <strong>@Translate("Smartpage:LiveshoppingActiveCampaignSignUpModal.Signup", "Tilmelding")</strong> 14032 </div> 14033 </div> 14034 <div class="modal__body"> 14035 @activeCampaignForm 14036 </div> 14037 <label class="modal__close-btn" for="LiveshoppingActiveCampaignSignUpModalTrigger"></label> 14038 </div> 14039 </div> 14040 } 14041 14042 @helper RenderBooztDiscountTermsConditionsModal(Smartpage.PhilipsonWine.EcomDiscount.Model.BooztDiscount booztDiscount) 14043 { 14044 int quantity = booztDiscount.Discount.BooztDiscountQuantity; 14045 int amount = booztDiscount.Discount.BooztDiscountAmount; 14046 string quantityPluralCheck = quantity > 1 ? Translate("Custom:BooztDiscount.TermsConditions.Modal.Products.Pluralis", "varer") : Translate("Custom:BooztDiscount.TermsConditions.Modal.Product.Singular", "vare"); 14047 int termsAndConditionsPageId = GetPageIdByNavigationTag("TermsAndConditions"); 14048 14049 <input type="checkbox" id="OptionalDiscountTermsConditionsModalTrigger_@booztDiscount.Discount.Discount.ID" class="modal-trigger"> 14050 <div class="modal-container"> 14051 <label for="OptionalDiscountTermsConditionsModalTrigger_@booztDiscount.Discount.Discount.ID" class="modal-overlay"></label> 14052 <div class="modal modal--md modal-height--auto" id="OptionalDiscountTermsConditionsModal"> 14053 <div class="modal__header"> 14054 <div class="u-ta-center header-text"> 14055 <h3 class="custom-optional-discount-terms-conditions-modal-header">@Translate("Custom:BooztDiscount.TermsConditions.Modal.Header", "Aktiver tilbud")</h3> 14056 </div> 14057 </div> 14058 <div class="modal__body"> 14059 <ul> 14060 @if (termsAndConditionsPageId > 0) 14061 { 14062 <li> 14063 <a class="u-underline" href="/Default.aspx?ID=@termsAndConditionsPageId">@Translate("Custom:BooztDiscount.TermsConditions.Modal.Body.List.TermsConditionsLink", "Philipson Wine vilkår og betingelser er gældende")</a> 14064 </li> 14065 } 14066 14067 <li>@Translate("Custom:BooztDiscount.TermsConditions.Modal.Body.List.OnlyApplicableFor", "Kun varer, der er markeret med kampagnebanneret, er omfattet af kampagnen")</li> 14068 14069 @if (quantity > 0 && amount <= 0) 14070 { 14071 <li>@string.Format(Translate("Custom:BooztDiscount.TermsConditions.Modal.Body.List.QuantityOnlyRequirement", "Der skal købes mindst {0} {1}, før dette tilbud kan anvendes"), quantity, quantityPluralCheck)</li> 14072 } 14073 else if (quantity <= 0 && amount > 0) 14074 { 14075 <li>@string.Format(Translate("Custom:BooztDiscount.TermsConditions.Modal.Body.List.AmountOnlyRequirement", "Den sammenlagte ordreværdi skal mindst være {0} {1}, før dette tilbud kan anvendes"), amount, Dynamicweb.Ecommerce.Common.Context.Currency.Symbol)</li> 14076 } 14077 else if (quantity > 0 && amount > 0) 14078 { 14079 <li>@string.Format(Translate("Custom:BooztDiscount.TermsConditions.Modal.Body.List.QuantityAndAmountRequirements", "Der skal købes mindst {0} {1} for mindst {2} {3} i den sammenlagte ordreværdi, før dette tilbud kan anvendes"), quantity, quantityPluralCheck, amount, Dynamicweb.Ecommerce.Common.Context.Currency.Symbol)</li> 14080 } 14081 </ul> 14082 </div> 14083 <div class="modal__footer"> 14084 <label class="btn btn--primary dw-mod u-margin-auto u-block u-width-max-content" for="OptionalDiscountTermsConditionsModalTrigger_@booztDiscount.Discount.Discount.ID">@Translate("Custom:BooztDiscount.TermsConditions.Modal.Footer.AcceptTerms", "Ok, jeg forstår")</label> 14085 </div> 14086 <label class="modal__close-btn" for="OptionalDiscountTermsConditionsModalTrigger_@booztDiscount.Discount.Discount.ID"></label> 14087 </div> 14088 </div> 14089 } 14090 14091 @helper RenderUserEditModal() 14092 { 14093 14094 <input type="checkbox" id="UserEditModalTrigger" class="modal-trigger"> 14095 14096 <div class="modal-container useredit-modal js-useredit-modal" data-usereditpageurl="/Default.aspx?ID=@GetPageIdByNavigationTag("useredit")"> 14097 <label class="modal-overlay model-overlay--disallow"></label> 14098 <div class="modal modal--lg modal-height--auto" id="UserEditModal"> 14099 <div class="modal__header"> 14100 <div class="u-ta-center header-text u-flex u-flex--column"> 14101 <strong>@Translate("Smartpage:UsereditModal.Title", "Opdatér brugerinfo")</strong> 14102 <span class="u-font-size--md">@Translate("Smartpage:UsereditModal.Subtitle", "Lorem ipsum")</span> 14103 </div> 14104 </div> 14105 <div class="modal__body js-useredit-modal-body"> 14106 </div> 14107 <p class="js-useredit-form-respons-error u-no-margin--bottom u-hidden u-ta-center">@Translate("Smartpage:UsereditModal.Error", "Kunne ikke opdatere")</p> 14108 </div> 14109 </div> 14110 <script> 14111 var modalTrigger = document.getElementById('UserEditModalTrigger'); 14112 if (modalTrigger != null) { 14113 modalTrigger.checked = true; 14114 } 14115 </script> 14116 } 14117 14118 @helper RenderBusinessContactImpersonationModal() 14119 { 14120 <input type="checkbox" id="BusinessContactImpersonationModalTrigger" class="modal-trigger"> 14121 14122 <div class="modal-container impersonation-modal js-impersonation-modal"> 14123 <label class="modal-overlay model-overlay--disallow"></label> 14124 <div class="modal modal--lg modal-height--auto" id="BusinessContactImpersonationModal"> 14125 <div class="modal__header"> 14126 <div class="u-ta-center header-text u-flex u-flex--column"> 14127 @Translate("Smartpage:BusinessContactImpersonationModal.Header", "Ønsker du at handle på vegne af en anden kunde?") 14128 </div> 14129 </div> 14130 <div class="modal__body js-impersonation-modal-body"> 14131 @if (Model.CurrentSecondaryUser != null && Model.CurrentSecondaryUser.ID > 0 && Model.CurrentUser != null && Model.CurrentUser.ID > 0) 14132 { 14133 <div class="u-ta-center u-margin-bottom">@Translate("Smartpage:BusinessContactImpersonationModal.CurrentSecondaryUser", "Du handler i øjeblikket på vegne af"): @Model.CurrentUser.Company</div> 14134 } 14135 <div class="grid"> 14136 <div class="grid__col-sm-auto"> 14137 @if (Model.CurrentSecondaryUser != null && Model.CurrentSecondaryUser.ID > 0) 14138 { 14139 <form method="post" class="u-no-margin u-full-width"> 14140 <button class="btn btn--secondary u-no-margin--bottom dw-mod u-full-width" name="DwExtranetRemoveSecondaryUser" onclick="location.href='@Dynamicweb.Context.Current.Request.Url.PathAndQuery'" type="submit"> 14141 @Translate("Smartpage:BusinessContactImpersonationModal.No", "Nej - jeg vil selv købe") 14142 </button> 14143 </form> 14144 } 14145 else 14146 { 14147 <button class="btn btn--secondary u-no-margin--bottom dw-mod js-dismiss-modal" onclick="document.getElementById('BusinessContactImpersonationModalTrigger').checked = false;">@Translate("Smartpage:BusinessContactImpersonationModal.No", "Nej - jeg vil selv købe")</button> 14148 } 14149 </div> 14150 <div class="grid__col-sm-auto"> 14151 @if (Model.CurrentSecondaryUser != null && Model.CurrentSecondaryUser.ID > 0) 14152 { 14153 <button class="btn btn--secondary dw-mod u-no-margin--bottom" onclick="document.location.href='/Default.aspx?ID=@GetPageIdByNavigationTag("Impersonation")';">@Translate("Smartpage:BusinessContactImpersonationModal.ChangeCustomer", "Vælg anden kunde")</button> 14154 } 14155 else 14156 { 14157 <button class="btn btn--secondary dw-mod u-no-margin--bottom" onclick="document.location.href='/Default.aspx?ID=@GetPageIdByNavigationTag("Impersonation")';">@Translate("Smartpage:BusinessContactImpersonationModal.CustomerList", "Ja - vis kundeliste")</button> 14158 } 14159 </div> 14160 </div> 14161 </div> 14162 <label class="modal__close-btn" for="BusinessContactImpersonationModalTrigger"></label> 14163 </div> 14164 </div> 14165 <script> 14166 var modalTrigger = document.getElementById('BusinessContactImpersonationModalTrigger'); 14167 if (modalTrigger != null) { 14168 modalTrigger.checked = true; 14169 } 14170 </script> 14171 } 14172 14173 @helper RenderShareUrlModal() 14174 { 14175 string currentUrl = Dynamicweb.Context.Current.Request.Url.Scheme + "://" + Dynamicweb.Context.Current.Request.Url.Host + Dynamicweb.Context.Current.Request.RawUrl; 14176 var shareOnMediaList = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetItems("ShareOnMediaList"); 14177 if (shareOnMediaList != null && shareOnMediaList.Any()) 14178 { 14179 int productId = Converter.ToInt32(Dynamicweb.Context.Current.Request["ProductId"]); 14180 string productName = Dynamicweb.Ecommerce.Services.Products.GetProductById(Dynamicweb.Context.Current.Request["ProductId"], string.Empty, Dynamicweb.Ecommerce.Common.Context.LanguageID)?.Name; 14181 14182 <input type="checkbox" id="ShareUrlModalTrigger" class="modal-trigger"> 14183 <div id="ShareUrlModal" class="modal-container js-share-url-modal"> 14184 <label class="modal-overlay js-share-url-close-modal"></label> 14185 <div class="modal modal--md modal-height--auto"> 14186 <div class="modal__header"> 14187 <div class="u-ta-center header-text u-flex u-flex--column"> 14188 <strong>@Translate("Custom:ShareUrlModal.Title", "Del linket med dine venner!")</strong> 14189 </div> 14190 </div> 14191 <div class="modal__body"> 14192 <div class="share-media-options-container"> 14193 @foreach (var media in shareOnMediaList) 14194 { 14195 string mediaLogo = media.GetRawValueString("MediaLogo"); 14196 string shareUrl = media.GetRawValueString("ShareUrl"); 14197 if (!string.IsNullOrEmpty(mediaLogo) && !string.IsNullOrEmpty(shareUrl)) 14198 { 14199 // CDN 14200 var cdnUrl = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetRawValueString("CDNUrl"); 14201 bool cdnActivate = Dynamicweb.Frontend.PageView.Current().AreaSettings.GetItem("Custom").GetBoolean("CDNActivate"); 14202 if (!string.IsNullOrWhiteSpace(cdnUrl) && cdnActivate) 14203 { 14204 mediaLogo = cdnUrl + mediaLogo; 14205 } 14206 14207 string constructedUrl = shareUrl + HttpUtility.HtmlAttributeEncode(Converter.ToString(currentUrl)); 14208 bool isDesktop = Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Desktop; 14209 bool showOnDesktop = media.GetBoolean("ShowOnDesktop"); 14210 14211 if (!isDesktop || showOnDesktop) 14212 { 14213 string viewClickData = Smartpage.Tracking.Models.CustomTrackingDataLayer.CustomViewClickData((productId > 0 ? productId : Model.ID), media.GetRawValueString("MediaName"), Translate("Custom:DataLayer.ViewClick.SharePage.CreativeSlot", "Share page on media"), constructedUrl, currentUrl, Converter.ToString(Pageview.Device)); 14214 14215 <a class="share-media-option-button js-view-click-share-url-event-trigger" href="@constructedUrl" target="_blank" data-params="@HttpUtility.HtmlAttributeEncode(viewClickData)"> 14216 <img class="share-media-option-img" src="@mediaLogo" /> 14217 </a> 14218 } 14219 } 14220 } 14221 </div> 14222 </div> 14223 <div class="modal__body"> 14224 <div class="u-font-size--md u-bold u-flex u-justify-content--center u-padding--lg">@Translate("Custom:ShareUrlModal.CopyToClipboard.Header", "Eller kopiér linket her:")</div> 14225 <div class="u-flex u-justify-content--center content-row--column-gap-sm"> 14226 <input class="share-url-input" type="text" value="@currentUrl" readonly /> 14227 <button class="btn btn--primary dw-mod js-share-url-copy-button js-view-click-share-url-event-trigger" data-alert-text="@HttpUtility.HtmlAttributeEncode(Translate("Custom:ShareUrlModal.CopyToClipboard.AlertText", "Du har kopieret linket til denne side. Del linket med dine venner og bekendte!"))" data-current-url="@HttpUtility.HtmlAttributeEncode(currentUrl)" data-params="@HttpUtility.HtmlAttributeEncode(Smartpage.Tracking.Models.CustomTrackingDataLayer.CustomViewClickData(productId, productName, Translate("Custom:DataLayer.ViewClick.ShareUrlModal.CopyToClipboard.CreativeSlot", "Copy to clipboard"), currentUrl, currentUrl, Converter.ToString(Pageview.Device)))">@Translate("Custom:ShareUrlModal.CopyToClipboard.Button", "Kopiér")</button> 14228 </div> 14229 </div> 14230 <label class="modal__close-btn js-share-url-close-modal" for="ShareUrlModalTrigger"></label> 14231 </div> 14232 </div> 14233 } 14234 } 14235 14236 @if (!isFooterHidden) 14237 { 14238 <text>@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 14239 14240 @using System 14241 @using System.Web 14242 @using System.Collections.Generic 14243 @using Dynamicweb.Rapido.Blocks.Extensibility 14244 @using Dynamicweb.Rapido.Blocks 14245 @using Dynamicweb.Rapido.Blocks.Components.General 14246 @using Custom.PhilipsonWine.Security.Helpers 14247 14248 @functions { 14249 BlocksPage footerBlocksPage = BlocksPage.GetBlockPage("Master"); 14250 } 14251 14252 @{ 14253 string footerColumnOneContent = Model.Area.Item.GetItem("Layout").GetItem("FooterColumnOne").GetString("Content"); 14254 string footerColumnTwoContent = Model.Area.Item.GetItem("Layout").GetItem("FooterColumnTwo").GetString("Content"); 14255 string footerColumnThreeContent = Model.Area.Item.GetItem("Layout").GetItem("FooterColumnThree").GetString("Content"); 14256 string footerColumnOneHeader = Model.Area.Item.GetItem("Layout").GetItem("FooterColumnOne").GetString("Header"); 14257 string footerColumnTwoHeader = Model.Area.Item.GetItem("Layout").GetItem("FooterColumnTwo").GetString("Header"); 14258 string footerColumnThreeHeader = Model.Area.Item.GetItem("Layout").GetItem("FooterColumnThree").GetString("Header"); 14259 string footerColumnFourContent = Model.Area.Item.GetItem("Layout").GetString("FooterColumnFourTrustpilot"); 14260 14261 // Banner columns 14262 string footerBannerColumnOneContent = Model.Area.Item.GetItem("Layout").GetItem("FooterBannerColumnOne")?.GetString("Content"); 14263 string footerBannerColumnOneIcon = Model.Area.Item.GetItem("Layout").GetItem("FooterBannerColumnOne")?.GetString("Icon"); 14264 string footerBannerColumnTwoContent = Model.Area.Item.GetItem("Layout").GetItem("FooterBannerColumnTwo")?.GetString("Content"); 14265 string footerBannerColumnTwoIcon = Model.Area.Item.GetItem("Layout").GetItem("FooterBannerColumnTwo")?.GetString("Icon"); 14266 string footerBannerColumnThreeContent = Model.Area.Item.GetItem("Layout").GetItem("FooterBannerColumnThree")?.GetString("Content"); 14267 string footerBannerColumnThreeIcon = Model.Area.Item.GetItem("Layout").GetItem("FooterBannerColumnThree")?.GetString("Icon"); 14268 14269 // Bottom columns 14270 string footerBottomColumnOneContent = Model.Area.Item.GetItem("Layout").GetItem("FooterBottomColumnOne")?.GetString("Content"); 14271 string footerBottomColumnOneHeader = Model.Area.Item.GetItem("Layout").GetItem("FooterBottomColumnOne")?.GetString("Header"); 14272 string footerBottomColumnTwoContent = Model.Area.Item.GetItem("Layout").GetItem("FooterBottomColumnTwo")?.GetString("Content"); 14273 string footerBottomColumnTwoHeader = Model.Area.Item.GetItem("Layout").GetItem("FooterBottomColumnTwo")?.GetString("Header"); 14274 string footerBottomColumnThreeContent = Model.Area.Item.GetItem("Layout").GetItem("FooterBottomColumnThree")?.GetString("Content"); 14275 string footerBottomColumnThreeHeader = Model.Area.Item.GetItem("Layout").GetItem("FooterBottomColumnThree")?.GetString("Header"); 14276 14277 bool isDesktop = Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Desktop; 14278 14279 // FOOTER BANNER CONTAINER 14280 Block masterFooterBannerContent = new Block() 14281 { 14282 Id = "MasterFooterBannerContent", 14283 SortId = 10, 14284 Template = RenderFooterBanner(), 14285 SkipRenderBlocksList = true 14286 }; 14287 footerBlocksPage.Add(MasterBlockId.MasterFooter, masterFooterBannerContent); 14288 14289 14290 // FOOTER COLUMNS CONTAINER 14291 Block masterFooterContent = new Block() 14292 { 14293 Id = "MasterFooterContent", 14294 SortId = 20, 14295 Template = RenderFooter(), 14296 SkipRenderBlocksList = true 14297 }; 14298 footerBlocksPage.Add(MasterBlockId.MasterFooter, masterFooterContent); 14299 14300 14301 // FOOTER BOTTOM CONTAINER 14302 Block masterFooterBottomContent = new Block() 14303 { 14304 Id = "MasterFooterBottomContent", 14305 SortId = 30, 14306 Template = RenderFooterBottom(), 14307 SkipRenderBlocksList = true 14308 }; 14309 footerBlocksPage.Add(MasterBlockId.MasterFooter, masterFooterBottomContent); 14310 14311 if (!string.IsNullOrEmpty(footerBannerColumnOneContent) && !string.IsNullOrEmpty(footerBannerColumnOneIcon)) 14312 { 14313 if (isDesktop) 14314 { 14315 Block masterFooterBannerColumnOne = new Block 14316 { 14317 Id = "MasterFooterColumnOne", 14318 SortId = 10, 14319 Template = RenderFooterBannerColumn(footerBannerColumnOneIcon, footerBannerColumnOneContent), 14320 Design = new Design 14321 { 14322 Size = "auto", 14323 RenderType = RenderType.Column, 14324 CssClass = "u-justify-content--center" 14325 } 14326 }; 14327 footerBlocksPage.Add("MasterFooterBannerContent", masterFooterBannerColumnOne); 14328 } 14329 else 14330 { 14331 Block masterFooterBannerColumnOne = new Block 14332 { 14333 Id = "MasterFooterColumnOne", 14334 SortId = 10, 14335 Template = RenderFooterBannerColumn(footerBannerColumnOneIcon, footerBannerColumnOneContent), 14336 Design = new Design 14337 { 14338 RenderType = RenderType.Column, 14339 CssClass = "u-justify-content--center grid__col-6 border-right border-bottom" 14340 } 14341 }; 14342 footerBlocksPage.Add("MasterFooterBannerContent", masterFooterBannerColumnOne); 14343 } 14344 } 14345 14346 if (!string.IsNullOrEmpty(footerBannerColumnTwoContent) && !string.IsNullOrEmpty(footerBannerColumnTwoIcon)) 14347 { 14348 if (isDesktop) 14349 { 14350 Block masterFooterBannerColumnTwo = new Block 14351 { 14352 Id = "MasterFooterColumnOne", 14353 SortId = 20, 14354 Template = RenderFooterBannerColumn(footerBannerColumnTwoIcon, footerBannerColumnTwoContent), 14355 Design = new Design 14356 { 14357 Size = "auto", 14358 RenderType = RenderType.Column, 14359 CssClass = "u-justify-content--center" 14360 } 14361 }; 14362 footerBlocksPage.Add("MasterFooterBannerContent", masterFooterBannerColumnTwo); 14363 } 14364 else 14365 { 14366 Block masterFooterBannerColumnTwo = new Block 14367 { 14368 Id = "MasterFooterColumnOne", 14369 SortId = 20, 14370 Template = RenderFooterBannerColumn(footerBannerColumnTwoIcon, footerBannerColumnTwoContent), 14371 Design = new Design 14372 { 14373 RenderType = RenderType.Column, 14374 CssClass = "u-justify-content--center grid__col-6 border-bottom" 14375 } 14376 }; 14377 footerBlocksPage.Add("MasterFooterBannerContent", masterFooterBannerColumnTwo); 14378 } 14379 } 14380 14381 if (!string.IsNullOrEmpty(footerBannerColumnThreeContent) && !string.IsNullOrEmpty(footerBannerColumnThreeIcon)) 14382 { 14383 if (isDesktop) 14384 { 14385 Block masterFooterBannerColumnThree = new Block 14386 { 14387 Id = "MasterFooterColumnOne", 14388 SortId = 20, 14389 Template = RenderFooterBannerColumn(footerBannerColumnThreeIcon, footerBannerColumnThreeContent), 14390 Design = new Design 14391 { 14392 Size = "auto", 14393 RenderType = RenderType.Column, 14394 CssClass = "u-justify-content--center" 14395 } 14396 }; 14397 footerBlocksPage.Add("MasterFooterBannerContent", masterFooterBannerColumnThree); 14398 } 14399 else 14400 { 14401 Block masterFooterBannerColumnThree = new Block 14402 { 14403 Id = "MasterFooterColumnOne", 14404 SortId = 20, 14405 Template = RenderFooterBannerColumn(footerBannerColumnThreeIcon, footerBannerColumnThreeContent), 14406 Design = new Design 14407 { 14408 RenderType = RenderType.Column, 14409 CssClass = "u-justify-content--center grid__col-6 border-right" 14410 } 14411 }; 14412 footerBlocksPage.Add("MasterFooterBannerContent", masterFooterBannerColumnThree); 14413 } 14414 } 14415 14416 var footerSocialBanner = Model.Area.Item.GetItem("Layout").GetItem("FooterBannerSocial"); 14417 if (footerSocialBanner != null && footerSocialBanner.GetItems("Icons").Any()) 14418 { 14419 if (isDesktop) 14420 { 14421 Block masterFooterSocialLinks = new Block 14422 { 14423 Id = "MasterFooterSocialLinks", 14424 SortId = 50, 14425 Template = RenderFooterSocialLinks(footerSocialBanner), 14426 Design = new Design 14427 { 14428 Size = "auto", 14429 RenderType = RenderType.Column, 14430 CssClass = "u-justify-content--center" 14431 } 14432 }; 14433 footerBlocksPage.Add("MasterFooterBannerContent", masterFooterSocialLinks); 14434 } 14435 else 14436 { 14437 Block masterFooterSocialLinks = new Block 14438 { 14439 Id = "MasterFooterSocialLinks", 14440 SortId = 50, 14441 Template = RenderFooterSocialLinks(footerSocialBanner), 14442 Design = new Design 14443 { 14444 RenderType = RenderType.Column, 14445 CssClass = "u-justify-content--center grid__col-6" 14446 } 14447 }; 14448 footerBlocksPage.Add("MasterFooterBannerContent", masterFooterSocialLinks); 14449 } 14450 } 14451 14452 // Footer top columns 14453 14454 if (!string.IsNullOrEmpty(footerColumnOneContent) || !string.IsNullOrEmpty(footerColumnOneHeader)) 14455 { 14456 if (isDesktop) 14457 { 14458 Block masterFooterColumnOne = new Block 14459 { 14460 Id = "MasterFooterColumnOne", 14461 SortId = 10, 14462 Template = RenderFooterColumn(footerColumnOneHeader, footerColumnOneContent), 14463 Design = new Design 14464 { 14465 Size = "auto", 14466 RenderType = RenderType.Column 14467 } 14468 }; 14469 footerBlocksPage.Add("MasterFooterContent", masterFooterColumnOne); 14470 } 14471 else 14472 { 14473 Block masterFooterColumnOne = new Block 14474 { 14475 Id = "MasterFooterColumnOne", 14476 SortId = 10, 14477 Template = RenderFooterColumn(footerColumnOneHeader, footerColumnOneContent), 14478 Design = new Design 14479 { 14480 RenderType = RenderType.Column, 14481 CssClass = "grid__col-6 mobile-order-1" 14482 } 14483 }; 14484 footerBlocksPage.Add("MasterFooterContent", masterFooterColumnOne); 14485 } 14486 } 14487 14488 if (!string.IsNullOrEmpty(footerColumnTwoContent) || !string.IsNullOrEmpty(footerColumnTwoHeader)) 14489 { 14490 if (isDesktop) 14491 { 14492 Block masterFooterColumnTwo = new Block 14493 { 14494 Id = "MasterFooterColumnTwo", 14495 SortId = 20, 14496 Template = RenderFooterColumn(footerColumnTwoHeader, footerColumnTwoContent), 14497 Design = new Design 14498 { 14499 Size = "auto", 14500 RenderType = RenderType.Column 14501 } 14502 }; 14503 footerBlocksPage.Add("MasterFooterContent", masterFooterColumnTwo); 14504 } 14505 } 14506 14507 if (!string.IsNullOrEmpty(footerColumnThreeContent) || !string.IsNullOrEmpty(footerColumnThreeHeader)) 14508 { 14509 if (isDesktop) 14510 { 14511 Block masterFooterColumnThree = new Block 14512 { 14513 Id = "MasterFooterColumnThree", 14514 SortId = 30, 14515 Template = RenderFooterColumn(footerColumnThreeHeader, footerColumnThreeContent), 14516 Design = new Design 14517 { 14518 Size = "auto", 14519 RenderType = RenderType.Column 14520 } 14521 }; 14522 footerBlocksPage.Add("MasterFooterContent", masterFooterColumnThree); 14523 } 14524 else 14525 { 14526 Block masterFooterColumnThree = new Block 14527 { 14528 Id = "MasterFooterColumnThree", 14529 SortId = 30, 14530 Template = RenderFooterColumn(footerColumnThreeHeader, footerColumnThreeContent), 14531 Design = new Design 14532 { 14533 RenderType = RenderType.Column, 14534 CssClass = "grid__col-6 mobile-order-1" 14535 } 14536 }; 14537 footerBlocksPage.Add("MasterFooterContent", masterFooterColumnThree); 14538 } 14539 } 14540 14541 if (!string.IsNullOrEmpty(footerColumnFourContent)) 14542 { 14543 if (isDesktop) 14544 { 14545 Block masterFooterTrustpilot = new Block 14546 { 14547 Id = "MasterFooterTrustpilot", 14548 SortId = 40, 14549 Template = RenderTrustpilotWidget(footerColumnFourContent), 14550 Design = new Design 14551 { 14552 Size = "auto", 14553 RenderType = RenderType.Column 14554 } 14555 }; 14556 footerBlocksPage.Add("MasterFooterContent", masterFooterTrustpilot); 14557 } 14558 else 14559 { 14560 Block masterFooterTrustpilot = new Block 14561 { 14562 Id = "MasterFooterTrustpilot", 14563 SortId = 40, 14564 Template = RenderTrustpilotWidget(footerColumnFourContent), 14565 Design = new Design 14566 { 14567 Size = "12", 14568 RenderType = RenderType.Column, 14569 CssClass = "mobile-order-7" 14570 } 14571 }; 14572 footerBlocksPage.Add("MasterFooterContent", masterFooterTrustpilot); 14573 } 14574 } 14575 14576 // Footer USP 14577 var footerUsp = Model.Area.Item.GetItem("Layout").GetItems("FooterUSP"); 14578 if (footerUsp != null && footerUsp.Any()) 14579 { 14580 Block masterUSP = new Block 14581 { 14582 Id = "MasterUSP", 14583 SortId = 50, 14584 Template = RenderFooterUSP(footerUsp), 14585 Design = new Design 14586 { 14587 Size = "12", 14588 RenderType = RenderType.Column, 14589 CssClass = "footer__usp mobile-order-2" 14590 } 14591 }; 14592 footerBlocksPage.Add("MasterFooterContent", masterUSP); 14593 14594 } 14595 14596 14597 // Footer bottom columns 14598 if (!string.IsNullOrEmpty(footerBottomColumnOneContent) || !string.IsNullOrEmpty(footerBottomColumnOneHeader)) 14599 { 14600 if (isDesktop) 14601 { 14602 Block masterFooterBottomColumnOne = new Block 14603 { 14604 Id = "MasterFooterBottomColumnOne", 14605 SortId = 60, 14606 Template = RenderFooterBottomColumn(footerBottomColumnOneHeader, footerBottomColumnOneContent), 14607 Design = new Design 14608 { 14609 Size = "3", 14610 RenderType = RenderType.Column, 14611 CssClass = "footer__bottom" 14612 } 14613 }; 14614 footerBlocksPage.Add("MasterFooterContent", masterFooterBottomColumnOne); 14615 } 14616 else 14617 { 14618 Block masterFooterBottomColumnOne = new Block 14619 { 14620 Id = "MasterFooterBottomColumnOne", 14621 SortId = 60, 14622 Template = RenderFooterBottomColumn(footerBottomColumnOneHeader, footerBottomColumnOneContent), 14623 Design = new Design 14624 { 14625 RenderType = RenderType.Column, 14626 CssClass = "footer__bottom mobile-order-3 grid__col-6" 14627 } 14628 }; 14629 footerBlocksPage.Add("MasterFooterContent", masterFooterBottomColumnOne); 14630 } 14631 } 14632 14633 if (!string.IsNullOrEmpty(footerBottomColumnTwoContent) || !string.IsNullOrEmpty(footerBottomColumnTwoHeader)) 14634 { 14635 if (isDesktop) 14636 { 14637 Block masterFooterBottomColumnTwo = new Block 14638 { 14639 Id = "MasterFooterBottomColumnTwo", 14640 SortId = 70, 14641 Template = RenderFooterBottomColumn(footerBottomColumnTwoHeader, footerBottomColumnTwoContent), 14642 Design = new Design 14643 { 14644 Size = "3", 14645 RenderType = RenderType.Column, 14646 CssClass = "footer__bottom" 14647 } 14648 }; 14649 footerBlocksPage.Add("MasterFooterContent", masterFooterBottomColumnTwo); 14650 } 14651 else 14652 { 14653 Block masterFooterBottomColumnTwo = new Block 14654 { 14655 Id = "MasterFooterBottomColumnTwo", 14656 SortId = 70, 14657 Template = RenderFooterBottomColumn(footerBottomColumnTwoHeader, footerBottomColumnTwoContent), 14658 Design = new Design 14659 { 14660 RenderType = RenderType.Column, 14661 CssClass = "footer__bottom mobile-order-4 grid__col-6" 14662 } 14663 }; 14664 footerBlocksPage.Add("MasterFooterContent", masterFooterBottomColumnTwo); 14665 } 14666 } 14667 14668 if (!string.IsNullOrEmpty(footerBottomColumnThreeContent) || !string.IsNullOrEmpty(footerBottomColumnThreeHeader)) 14669 { 14670 if (isDesktop) 14671 { 14672 Block masterFooterBottomColumnThree = new Block 14673 { 14674 Id = "MasterFooterBottomColumnOne", 14675 SortId = 80, 14676 Template = RenderFooterBottomColumn(footerBottomColumnThreeHeader, footerBottomColumnThreeContent), 14677 Design = new Design 14678 { 14679 Size = "3", 14680 RenderType = RenderType.Column, 14681 CssClass = "footer__bottom" 14682 } 14683 }; 14684 footerBlocksPage.Add("MasterFooterContent", masterFooterBottomColumnThree); 14685 } 14686 else 14687 { 14688 Block masterFooterBottomColumnThree = new Block 14689 { 14690 Id = "MasterFooterBottomColumnOne", 14691 SortId = 80, 14692 Template = RenderFooterBottomColumn(footerBottomColumnThreeHeader, footerBottomColumnThreeContent), 14693 Design = new Design 14694 { 14695 RenderType = RenderType.Column, 14696 CssClass = "footer__bottom grid__col-6 mobile-order-5" 14697 } 14698 }; 14699 footerBlocksPage.Add("MasterFooterContent", masterFooterBottomColumnThree); 14700 } 14701 } 14702 14703 if (Model.Area.Item.GetItem("Layout").GetBoolean("FooterNewsletterSignUp")) 14704 { 14705 NewsletterSignupHelperContext newsletterSignupHelperContext = new NewsletterSignupHelperContext 14706 { 14707 Pageview = Pageview, 14708 GetPageIdByNavigationTag = tag => GetPageIdByNavigationTag(tag), 14709 Translate = (text, def) => Translate(text, def) 14710 }; 14711 14712 Block masterFooterNewsletterSignUp = new Block 14713 { 14714 Id = "MasterFooterNewsletterSignUp", 14715 SortId = 90, 14716 Template = RenderNewsletterSignUp(newsletterSignupHelperContext, "Footer", Model.Area.Item.GetItem("Custom").GetRawValueString("SignupNewsletterId")), 14717 Design = new Design 14718 { 14719 Size = "3", 14720 RenderType = RenderType.Column, 14721 CssClass = "footer__bottom mobile-order-6" 14722 } 14723 }; 14724 footerBlocksPage.Add("MasterFooterContent", masterFooterNewsletterSignUp); 14725 } 14726 14727 // LAST ROW 14728 14729 14730 if (isDesktop) 14731 { 14732 Block masterFooterCopyright = new Block 14733 { 14734 Id = "MasterFooterCopyright", 14735 SortId = 100, 14736 Template = RenderFooterCopyright(), 14737 Design = new Design 14738 { 14739 Size = "8", 14740 RenderType = RenderType.Column, 14741 CssClass = "u-flex--row grid--align-center" 14742 } 14743 }; 14744 footerBlocksPage.Add("MasterFooterBottomContent", masterFooterCopyright); 14745 } 14746 else 14747 { 14748 Block masterFooterCopyright = new Block 14749 { 14750 Id = "MasterFooterCopyright", 14751 SortId = 100, 14752 Template = RenderFooterCopyright(), 14753 Design = new Design 14754 { 14755 Size = "8", 14756 RenderType = RenderType.Column, 14757 CssClass = "u-flex--column grid--align-center" 14758 } 14759 }; 14760 footerBlocksPage.Add("MasterFooterBottomContent", masterFooterCopyright); 14761 } 14762 14763 14764 var footerPayments = Model.Area.Item.GetItem("Layout").GetItems("FooterPayments"); 14765 if (footerPayments != null && footerPayments.Any()) 14766 { 14767 Block masterFooterPayments = new Block 14768 { 14769 Id = "MasterFooterPayments", 14770 SortId = 110, 14771 Template = RenderFooterPayments(footerPayments), 14772 Design = new Design 14773 { 14774 Size = "4", 14775 RenderType = RenderType.Column 14776 } 14777 }; 14778 footerBlocksPage.Add("MasterFooterBottomContent", masterFooterPayments); 14779 } 14780 } 14781 14782 @helper RenderFooter() 14783 { 14784 List<Block> subBlocks = this.footerBlocksPage.GetBlockListById("MasterFooterContent").OrderBy(item => item.SortId).ToList(); 14785 14786 <footer class="footer dw-mod"> 14787 <div class="center-container top-container__center-container dw-mod"> 14788 <div class="grid grid--external-bleed-x u-justify-content--center"> 14789 @RenderBlockList(subBlocks) 14790 </div> 14791 </div> 14792 </footer> 14793 } 14794 14795 @helper RenderFooterBanner() 14796 { 14797 List<Block> subBlocks = this.footerBlocksPage.GetBlockListById("MasterFooterBannerContent").OrderBy(item => item.SortId).ToList(); 14798 14799 <footer class="footer__banner dw-mod"> 14800 <div class="center-container top-container__center-container dw-mod"> 14801 <div class="grid grid--external-bleed-x u-full-height"> 14802 @RenderBlockList(subBlocks) 14803 </div> 14804 </div> 14805 </footer> 14806 } 14807 14808 @helper RenderFooterBottom() 14809 { 14810 List<Block> subBlocks = this.footerBlocksPage.GetBlockListById("MasterFooterBottomContent").OrderBy(item => item.SortId).ToList(); 14811 14812 <footer class="footer__end dw-mod"> 14813 <div class="center-container top-container__center-container dw-mod"> 14814 <div class="grid grid--external-bleed-x u-full-height"> 14815 @RenderBlockList(subBlocks) 14816 </div> 14817 </div> 14818 </footer> 14819 } 14820 14821 @helper RenderFooterBannerColumn(string icon, string content) 14822 { 14823 <div class="footer__banner__container"> 14824 <div class="footer__banner__icon dw-mod"><img src="@icon" /></div> 14825 <div class="footer__banner__content dw-mod"> 14826 @content 14827 </div> 14828 </div> 14829 } 14830 14831 14832 @helper RenderFooterColumn(string header, string content) 14833 { 14834 <h3 class="footer__heading dw-mod">@header</h3> 14835 <div class="footer__content dw-mod"> 14836 @content 14837 </div> 14838 } 14839 14840 @helper RenderFooterBottomColumn(string header, string content) 14841 { 14842 <h3 class="footer__bottom__heading dw-mod">@header</h3> 14843 <div class="footer__bottom__content dw-mod"> 14844 @content 14845 </div> 14846 } 14847 14848 @helper RenderTrustpilotWidget(string content) 14849 { 14850 var footerBadges = Model.Area.Item.GetItem("Custom").GetItems("FooterBadges"); 14851 string trustpilotFreeWidget = Model.Area.Item.GetItem("Custom").GetString("FooterTrustpilotFreeWidget"); 14852 14853 @trustpilotFreeWidget 14854 14855 if (footerBadges != null) 14856 { 14857 <div class="footer-badges-flex"> 14858 @foreach (var badge in footerBadges) 14859 { 14860 string badgeImage = badge.GetString("FooterBadgeImage"); 14861 string badgeLink = badge.GetString("FooterBadgeLink"); 14862 if (!string.IsNullOrEmpty(badgeLink)) 14863 { 14864 <a href="@badgeLink" class="footer-badge-flex-item"> 14865 <img src="@badgeImage" /> 14866 </a> 14867 } 14868 else 14869 { 14870 <div class="footer-badge-flex-item"> 14871 <img src="@badgeImage" /> 14872 </div> 14873 } 14874 } 14875 </div> 14876 } 14877 } 14878 14879 @helper RenderFooterSocialLinks(Dynamicweb.Frontend.ItemViewModel footerSocialBanner) 14880 { 14881 var bannerContent = footerSocialBanner.GetString("Content"); 14882 var bannerItems = footerSocialBanner.GetItems("Icons"); 14883 14884 <div class="footer__banner__container social"> 14885 <div class="footer__banner__content"> 14886 <strong>@bannerContent</strong> 14887 </div> 14888 <div class="collection dw-mod"> 14889 @foreach (var socialitem in bannerItems) 14890 { 14891 string socialLink = socialitem.GetString("Link"); 14892 string socialIcon = socialitem.GetString("Icon"); 14893 string socialIconTitle = socialitem.GetString("Title"); 14894 14895 <a href="@socialLink" target="_blank" title="@socialIconTitle" class="u-margin-bottom-5px" rel="noopener"><img src="@socialIcon" /></a> 14896 } 14897 </div> 14898 </div> 14899 } 14900 14901 @helper RenderFooterPayments(IList<Dynamicweb.Frontend.ItemViewModel> footerPayments) 14902 { 14903 <div class="footer__end__content dw-mod"> 14904 <p class="d-none d-lg-block">@Translate("Altid sikker og krypteret betaling")</p> 14905 <div class="collection dw-mod"> 14906 @foreach (var payment in footerPayments) 14907 { 14908 var paymentItem = payment.GetValue("CardTypeOrVerifiedPayment") as Dynamicweb.Frontend.ListViewModel; 14909 string paymentImage = null; 14910 string paymentTitle = paymentItem.SelectedName; 14911 ListOptionViewModel selected = paymentItem.SelectedOptions.FirstOrDefault(); 14912 if (selected != null) 14913 { 14914 paymentImage = selected.Icon; 14915 } 14916 14917 <div class="footer__card-type"> 14918 <img class="b-lazy" src="/Files/Images/placeholder.gif" data-src="/Admin/Public/GetImage.ashx?width=60&Compression=75&image=@paymentImage" alt="@paymentTitle" title="@paymentTitle" /> 14919 </div> 14920 } 14921 </div> 14922 </div> 14923 } 14924 14925 @helper RenderFooterCopyright() 14926 { 14927 string logo = Model.Area.Item.GetItem("Layout").GetFile("LogoImage") != null ? Model.Area.Item.GetItem("Layout").GetFile("LogoImage").PathUrlEncoded : "/Files/Images/logo-dynamicweb.png"; 14928 if (Path.GetExtension(logo).ToLower() != ".svg") 14929 { 14930 int logoHeight = Model.Area.Item.GetItem("Layout").GetInt32("LogoHeight"); 14931 logoHeight = logoHeight > 0 && Pageview.Device != Dynamicweb.Frontend.Devices.DeviceType.Mobile ? logoHeight : 40; 14932 logo = "/Admin/Public/GetImage.ashx?height=" + Converter.ToString(logoHeight) + "&amp;crop=5&amp;Compression=75&amp;image=" + logo; 14933 } 14934 else 14935 { 14936 logo = HttpUtility.UrlDecode(logo); 14937 } 14938 14939 14940 <div class="footer__end__logo"><img src="@logo" /></div> 14941 <div class="footer__end__content"> 14942 @Model.Area.Item.GetItem("Layout").GetString("FooterCopyrightText") 14943 </div> 14944 } 14945 14946 @helper RenderFooterUSP(IList<Dynamicweb.Frontend.ItemViewModel> footerUsp) 14947 { 14948 <div class="grid dw-mod"> 14949 @foreach (var usp in footerUsp) 14950 { 14951 <div class="grid__col-lg-auto grid__col-md-auto grid__col-6 mobile-border dw-mod"> 14952 <div class="footer__usp__content"> 14953 <div class="icon"> 14954 <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" 14955 viewBox="0 0 408.576 408.576" style="enable-background:new 0 0 408.576 408.576;fill:#55DE9B" xml:space="preserve"> 14956 <g> 14957 <g> 14958 <path d="M204.288,0C91.648,0,0,91.648,0,204.288s91.648,204.288,204.288,204.288s204.288-91.648,204.288-204.288 14959 S316.928,0,204.288,0z M318.464,150.528l-130.56,129.536c-7.68,7.68-19.968,8.192-28.16,0.512L90.624,217.6 14960 c-8.192-7.68-8.704-20.48-1.536-28.672c7.68-8.192,20.48-8.704,28.672-1.024l54.784,50.176L289.28,121.344 14961 c8.192-8.192,20.992-8.192,29.184,0C326.656,129.536,326.656,142.336,318.464,150.528z" /> 14962 </g> 14963 </g> 14964 </svg> 14965 </div> 14966 <div class="usp">@usp.GetValue("Label")</div> 14967 </div> 14968 </div> 14969 } 14970 14971 </div> 14972 }</text> 14973 } 14974 14975 14976 @functions { 14977 public class ManifestIcon 14978 { 14979 public string src { get; set; } 14980 public string type { get; set; } 14981 public string sizes { get; set; } 14982 } 14983 14984 public class Manifest 14985 { 14986 public string name { get; set; } 14987 public string short_name { get; set; } 14988 public string start_url { get; set; } 14989 public string display { get; set; } 14990 public string background_color { get; set; } 14991 public string theme_color { get; set; } 14992 public List<ManifestIcon> icons { get; set; } 14993 } 14994 } 14995 14996 <!DOCTYPE html> 14997 14998 <html lang="@Pageview.Area.CultureInfo.TwoLetterISOLanguageName"> 14999 15000 15001 15002 @* The @RenderBlockList base helper is included in Components/GridBuilder.cshtml *@ 15003 @RenderBlockList(masterPage.BlocksRoot.BlocksList) 15004 15005 15006 15007 @helper RenderMasterHead() 15008 { 15009 List<Block> subBlocks = this.masterPage.GetBlockListById("Head").OrderBy(item => item.SortId).ToList(); 15010 15011 <head> 15012 <!-- Rapido version 3.3.1 --> 15013 15014 @RenderBlockList(subBlocks) 15015 </head> 15016 15017 } 15018 15019 @helper RenderMasterMetadata() 15020 { 15021 var swatches = new Dynamicweb.Content.Items.ColorSwatchService(); 15022 var brandColors = swatches.GetColorSwatch(1); 15023 string brandColorOne = brandColors.Palette["BrandColor1"]; 15024 15025 if (!String.IsNullOrEmpty(Model.Area.Item.GetItem("Settings").GetString("AppName")) && Model.Area.Item.GetItem("Settings").GetFile("AppIcon") != null) 15026 { 15027 Manifest manifest = new Manifest 15028 { 15029 name = Model.Area.Item.GetItem("Settings").GetString("AppName"), 15030 short_name = !String.IsNullOrEmpty(Model.Area.Item.GetItem("Settings").GetString("AppShortName")) ? Model.Area.Item.GetItem("Settings").GetString("AppShortName") : Model.Area.Item.GetItem("Settings").GetString("AppName"), 15031 start_url = "/", 15032 display = "standalone", 15033 background_color = Dynamicweb.Core.Converter.ToString(Model.Area.Item.GetItem("Settings").GetValue("AppBackgroundColor")), 15034 theme_color = Dynamicweb.Core.Converter.ToString(Model.Area.Item.GetItem("Settings").GetValue("AppThemeColor")) 15035 }; 15036 15037 manifest.icons = new List<ManifestIcon> { 15038 new ManifestIcon { 15039 src = "/Admin/Public/GetImage.ashx?width=192&height=192&crop=5&image=" + Model.Area.Item.GetItem("Settings").GetFile("AppIcon").PathUrlEncoded, 15040 sizes = "192x192", 15041 type = "image/png" 15042 }, 15043 new ManifestIcon { 15044 src = "/Admin/Public/GetImage.ashx?width=512&height=512&crop=5&image=" + Model.Area.Item.GetItem("Settings").GetFile("AppIcon").PathUrlEncoded, 15045 sizes = "512x512", 15046 type = "image/png" 15047 }, 15048 new ManifestIcon { 15049 src = "/Admin/Public/GetImage.ashx?width=1024&height=1024&crop=5&image=" + Model.Area.Item.GetItem("Settings").GetFile("AppIcon").PathUrlEncoded, 15050 sizes = "1024x1024", 15051 type = "image/png" 15052 } 15053 }; 15054 15055 string manifestFilePath = HttpContext.Current.Request.MapPath("/Files/Templates/Designs/Rapido/manifest.json"); 15056 string manifestJSON = Newtonsoft.Json.JsonConvert.SerializeObject(manifest); 15057 string currentManifest = File.ReadAllText(manifestFilePath); 15058 15059 if (manifestJSON != currentManifest) 15060 { 15061 File.WriteAllText(manifestFilePath, manifestJSON); 15062 } 15063 } 15064 15065 <meta charset="utf-8" /> 15066 <title>@Model.Title</title> 15067 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 15068 <meta name="robots" content="index, follow"> 15069 <meta name="theme-color" content="@brandColorOne" /> 15070 15071 if (Model.MetaTags != null && !Model.MetaTags.Contains("og:image") && Model.PropertyItem != null && Model.PropertyItem.GetFile("OpenGraphImage") != null) 15072 { 15073 Pageview.Meta.AddTag("og:image", string.Format("{0}://{1}{2}", Dynamicweb.Context.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Host, Model.PropertyItem.GetFile("OpenGraphImage"))); 15074 } 15075 15076 if (!Model.MetaTags.Contains("og:description") && !string.IsNullOrEmpty(Model.Description)) 15077 { 15078 Pageview.Meta.AddTag("og:description", Model.Description); 15079 } 15080 15081 Pageview.Meta.AddTag("og:title", Model.Title); 15082 Pageview.Meta.AddTag("og:site_name", Model.Name); 15083 Pageview.Meta.AddTag("og:url", HttpContext.Current.Request.Url.ToString()); 15084 Pageview.Meta.AddTag("og:type", "Website"); 15085 15086 if (!string.IsNullOrEmpty(Model.Area.Item.GetItem("Settings").GetString("FacebookAppID"))) 15087 { 15088 Pageview.Meta.AddTag("fb:app_id", Model.Area.Item.GetItem("Settings").GetString("FacebookAppID")); 15089 } 15090 15091 @Model.MetaTags 15092 } 15093 15094 @helper RenderMasterCss() 15095 { 15096 var fonts = new string[] { 15097 getFontFamily("Layout", "HeaderFont"), 15098 getFontFamily("Layout", "SubheaderFont"), 15099 getFontFamily("Layout", "TertiaryHeaderFont"), 15100 getFontFamily("Layout", "BodyText"), 15101 getFontFamily("Layout", "Header", "ToolsFont"), 15102 getFontFamily("Layout", "Header", "NavigationFont"), 15103 getFontFamily("Layout", "MobileNavigation", "Font"), 15104 getFontFamily("ProductList", "Facets", "HeaderFont"), 15105 getFontFamily("ProductPage", "PriceFontDesign"), 15106 getFontFamily("Ecommerce", "SaleSticker", "Font"), 15107 getFontFamily("Ecommerce", "NewSticker", "Font"), 15108 getFontFamily("Ecommerce", "CustomSticker", "Font") 15109 }; 15110 15111 string autoCssLink = "/Files/Templates/Designs/Rapido/css/rapido/rapido_" + Model.Area.ID.ToString() + ".min.css?ticks=" + Model.Area.UpdatedDate.Ticks; 15112 string favicon = Model.Area.Item.GetItem("Layout").GetFile("LogoFavicon") != null ? Model.Area.Item.GetItem("Layout").GetFile("LogoFavicon").Path : "/Files/Images/favicon.png"; 15113 bool useFontAwesomePro = Pageview.AreaSettings.GetItem("Layout").GetItem("Icons").GetBoolean("UseFontAwesomePro"); 15114 string fontAwesomeCssLink = "/Files/Templates/Designs/Rapido/css/fonts/FontAwesomeFree/css/fontawesome-all.min.css"; 15115 if (useFontAwesomePro) 15116 { 15117 fontAwesomeCssLink = "/Files/Templates/Designs/Rapido/css/fonts/FontAwesomePro/css/fontawesome-all.min.css"; 15118 } 15119 15120 var fileVersion = System.Web.HttpContext.Current.Cache["FileVersion"]; 15121 15122 //Favicon 15123 <link href="@favicon" rel="icon" type="image/png"> 15124 15125 //Base (Default, wireframe) styles 15126 <link rel="stylesheet" href="/Files/Templates/Designs/Rapido/css/base/base.min.css" type="text/css"> 15127 15128 //Rapido Css from Website Settings 15129 <link rel="stylesheet" id="rapidoCss" href="@autoCssLink" type="text/css"> 15130 15131 //Ignite Css (Custom site specific styles) 15132 <link rel="stylesheet" id="igniteCss" type="text/css" href="/Files/Templates/Designs/Rapido/css/ignite/ignite.min.css?v=@fileVersion"> 15133 15134 //Font awesome 15135 // Several references since all browser dont support preloading 15136 // Only one request are made per ressource 15137 <link rel="preload" as="style" href="@fontAwesomeCssLink"> 15138 <link rel="stylesheet" href="@fontAwesomeCssLink"> 15139 15140 //Flag icon 15141 <link rel="stylesheet" href="/Files/Templates/Designs/Rapido/css/fonts/flag-icon.min.css" type="text/css"> 15142 15143 //Google fonts 15144 var family = string.Join("%7C", fonts.Where(x => !string.IsNullOrEmpty(x)).Distinct().Select(x => string.Format("{0}:ital,100,200,300,400,500,600,700,800,900", x))); 15145 15146 <link href="https://fonts.googleapis.com/css?family=@family" rel="stylesheet"> 15147 15148 <link href="@fontAwesomeCssLink" rel="stylesheet"> 15149 <link href="/Files/Templates/Designs/Rapido/css/base/base.min.css" rel="stylesheet"> 15150 <link href="@autoCssLink" rel="stylesheet"> 15151 <link href="/Files/Templates/Designs/Rapido/css/ignite/ignite.min.css?v=@fileVersion" rel="stylesheet"> 15152 <link href="/Files/Templates/Designs/Rapido/css/fonts/flag-icon.min.css" rel="stylesheet"> 15153 15154 // Preload heavy things for faster pagespeed 15155 // Several references since all browser dont support preloading 15156 // Only one request are made per ressource 15157 <link rel="preload" as="font" type="font/woff2" crossorigin href="~/Files/Templates/Designs/Rapido/css/fonts/FontAwesomePro/webfonts/fa-brands-400.woff2" /> 15158 <link rel="stylesheet" type="font/woff2" crossorigin href="~/Files/Templates/Designs/Rapido/css/fonts/FontAwesomePro/webfonts/fa-brands-400.woff2" /> 15159 <link rel="preload" as="font" type="font/woff2" crossorigin href="~/Files/Templates/Designs/Rapido/css/fonts/FontAwesomePro/webfonts/fa-regular-400.woff2" /> 15160 <link rel="stylesheet" type="font/woff2" crossorigin href="~/Files/Templates/Designs/Rapido/css/fonts/FontAwesomePro/webfonts/fa-regular-400.woff2" /> 15161 <link rel="preload" as="font" type="font/woff2" crossorigin href="~/Files/Templates/Designs/Rapido/css/fonts/FontAwesomePro/webfonts/fa-light-300.woff2" /> 15162 <link rel="stylesheet" type="font/woff2" crossorigin href="~/Files/Templates/Designs/Rapido/css/fonts/FontAwesomePro/webfonts/fa-light-300.woff2" /> 15163 <link rel="preload" as="font" type="font/woff2" crossorigin href="~/Files/Templates/Designs/Rapido/css/fonts/FontAwesomePro/webfonts/fa-solid-900.woff2" /> 15164 <link rel="stylesheet" type="font/woff2" crossorigin href="~/Files/Templates/Designs/Rapido/css/fonts/FontAwesomePro/webfonts/fa-solid-900.woff2" /> 15165 15166 } 15167 15168 @helper RenderMasterManifest() 15169 { 15170 if (!String.IsNullOrEmpty(Model.Area.Item.GetItem("Settings").GetString("AppName"))) 15171 { 15172 <link rel="manifest" href="/Files/Templates/Designs/Rapido/manifest.json"> 15173 @*PushPromise("/Files/Templates/Designs/Rapido/manifest.json");*@ 15174 } 15175 } 15176 15177 @helper RenderMasterBody() 15178 { 15179 List<Block> subBlocks = this.masterPage.GetBlockListById("Body").OrderBy(item => item.SortId).ToList(); 15180 string designLayout = Model.PropertyItem.GetItem("CustomSettings") != null ? Model.PropertyItem.GetItem("CustomSettings").GetString("DesignLayout") != null ? Model.PropertyItem.GetItem("CustomSettings").GetList("DesignLayout").SelectedValue : "" : ""; 15181 15182 if (!string.IsNullOrEmpty(Dynamicweb.Context.Current.Request["ProductId"])) 15183 { 15184 designLayout += " on-product-page"; 15185 } 15186 15187 if (!string.IsNullOrEmpty(designLayout)) 15188 { 15189 designLayout = "class=\"" + designLayout + "\""; 15190 } 15191 else if (Pageview.Page.NavigationTag == "CartPage") 15192 { 15193 designLayout = "class=\"carts-page js-carts-page\""; 15194 } 15195 15196 <body @designLayout data-mini-cart-id="@GetPageIdByNavigationTag("MiniCartFeed")"> 15197 @RenderBlockList(subBlocks) 15198 </body> 15199 15200 } 15201 15202 @helper RenderMasterHeader() 15203 { 15204 List<Block> subBlocks = this.masterPage.GetBlockListById("MasterHeader").OrderBy(item => item.SortId).ToList(); 15205 bool isNavigationStickyMenu = Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Desktop && Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("StickyTop"); 15206 string stickyTop = isNavigationStickyMenu ? "top-container--sticky" : ""; 15207 15208 <header class="top-container @stickyTop js-top-container dw-mod" id="Top"> 15209 @RenderBlockList(subBlocks) 15210 </header> 15211 } 15212 15213 @helper RenderMain() 15214 { 15215 List<Block> subBlocks = this.masterPage.GetBlockListById("MasterMain").OrderBy(item => item.SortId).ToList(); 15216 bool isCocktailsPage = Dynamicweb.Context.Current.Request["ID"] == Converter.ToString(GetPageIdByNavigationTag("CocktailsPage")); 15217 15218 <main class="site dw-mod@(isCocktailsPage ? " custom-cocktails-page" : "")"> 15219 @RenderBlockList(subBlocks) 15220 </main> 15221 } 15222 15223 @helper RenderPageContent() 15224 { 15225 bool isNavigationStickyMenu = Pageview.Device == Dynamicweb.Frontend.Devices.DeviceType.Desktop && Model.Area.Item.GetItem("Layout").GetItem("Header").GetBoolean("StickyTop"); 15226 string pagePos = isNavigationStickyMenu ? "js-page-pos" : ""; 15227 15228 <div id="Page" class="page @pagePos"> 15229 <div id="content"> 15230 @RenderSnippet("Content") 15231 </div> 15232 </div> 15233 } 15234 15235 @helper RenderOverlay() 15236 { 15237 string menuType = Model.Area.Item.GetItem("Layout").GetItem("Header").GetList("NavigationMegaMenu") != null ? Model.Area.Item.GetItem("Layout").GetItem("Header").GetRawValueString("NavigationMegaMenu") : "dropdown"; 15238 if (menuType != "sidemenu") 15239 { 15240 <div id="js-page-overlay"> 15241 </div> 15242 } 15243 } 15244 15245 @* Hack to support nested helpers *@ 15246 @SnippetStart("Content") 15247 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel> 15248 15249 15250 @if (!Model.IsCurrentUserAllowed) 15251 { 15252 int signInPage = GetPageIdByNavigationTag("SignInPage"); 15253 int dashboardPage = GetPageIdByNavigationTag("CustomerDashboard"); 15254 int notValidLoginPage = GetPageIdByNavigationTag("NotValidLogin"); 15255 var user = Dynamicweb.Security.UserManagement.User.GetCurrentFrontendUser(); 15256 bool isEngrosSite = Pageview.AreaSettings.GetItem("Custom").GetBoolean("IsEngrosSite"); 15257 15258 if (!Pageview.IsVisualEditorMode) 15259 { 15260 if (signInPage != 0) 15261 { 15262 if (signInPage != Model.ID && user == null) 15263 { 15264 Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + signInPage); 15265 } 15266 else 15267 { 15268 if (isEngrosSite && notValidLoginPage != Model.ID && notValidLoginPage != 0 && user != null) 15269 { 15270 Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + notValidLoginPage); 15271 } 15272 else 15273 { 15274 if (dashboardPage != 0) 15275 { 15276 Dynamicweb.Context.Current.Response.Redirect("/Default.aspx?ID=" + dashboardPage); 15277 } 15278 else 15279 { 15280 Dynamicweb.Context.Current.Response.Redirect("/"); 15281 } 15282 } 15283 } 15284 } 15285 else 15286 { 15287 <div class="alert alert-dark m-0" role="alert"> 15288 <span>@Translate("You do not have access to this page")</span> 15289 </div> 15290 } 15291 } 15292 else 15293 { 15294 <div class="alert alert-dark m-0" role="alert"> 15295 <span>@Translate("To work on this page, you must be signed in, in the frontend")</span> 15296 </div> 15297 } 15298 } 15299 15300 @* Render the grid *@ 15301 @Model.Grid("Grid", "Grid", "default:true;sort:1", "Pages") 15302 15303 @if (Model.PropertyItem.GetBoolean("IsNewsLetterConfirmationPage")) 15304 { 15305 <script> 15306 window.dataLayer.push({ 15307 'event': 'newsLetterSignup', 15308 'signupType': 'footer', 15309 'shopId': '@Pageview.Area.EcomShopId', 15310 'areaId': '@Dynamicweb.Core.Converter.ToString(Pageview.AreaID)' 15311 }) 15312 </script> 15313 } 15314 @SnippetEnd("Content") 15315 15316 </html> 15317 15318