Directions for Partners - the go-to place for

Directions EMEA

Error executing template "Designs/Swift/Paragraph/COMM_Schedule.cshtml"
Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: d. Path '', line 0, position 0.
   at Newtonsoft.Json.JsonTextReader.ParseValue()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at CompiledRazorTemplates.Dynamic.RazorEngine_e99eda879a8c4d45943f7dd9cb606969.Execute() in C:\inetpub\wwwroot\directions2023\Files\Templates\Designs\Swift\Paragraph\COMM_Schedule.cshtml:line 177
   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()

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Frontend.Navigation 3 @using Dynamicweb.Content.Items 4 @using Dynamicweb.Frontend 5 @using System.Web.Helpers 6 @using System.Web 7 @using System.Text 8 @using System.Net 9 @using System.Linq 10 @using System 11 @using System.Globalization 12 @using Newtonsoft.Json 13 @using Newtonsoft.Json.Linq 14 15 @functions{ 16 static string GetJson(string address) 17 { 18 using (var client = new WebClient()) 19 { 20 client.Headers.Add("Content-Type", "application/json"); 21 try { 22 return client.DownloadString(address); 23 } catch (InvalidCastException e) 24 { 25 return ""; 26 } 27 } 28 } 29 30 string makeStringReadable(string data){ 31 string response = ""; 32 if(data != "") 33 { 34 string myStr = data; 35 byte[] bytes = Encoding.Default.GetBytes(myStr); 36 response = Encoding.UTF8.GetString(bytes); 37 } 38 return response; 39 } 40 41 42 43 public class Root 44 { 45 public List<Session> sessions {get; set;} 46 public List<Speaker> speakers {get; set;} 47 //public List<Question> questions {get; set;} 48 public List<Category> categories {get; set;} 49 public List<Item> rooms {get; set;} 50 } 51 52 public class Session 53 { 54 public string id {get; set;} 55 public string title {get; set;} 56 public string description {get; set;} 57 public DateTime? startsAt {get; set;} 58 public DateTime? endsAt {get; set;} 59 public bool isServiceSession {get; set;} 60 public bool isPlenumSession {get; set;} 61 public List<string> speakers {get; set;} 62 public List<int> categoryItems {get; set;} 63 public List<QuestionAnswers> questionAnswers {get; set;} 64 public int? roomId {get; set;} 65 public string room {get; set;} 66 public string liveUrl {get; set;} 67 public string recordingUrl {get; set;} 68 public string status {get; set;} 69 } 70 71 public class Speaker 72 { 73 public string id {get; set;} 74 public string firstName {get; set;} 75 public string lastName {get; set;} 76 public string bio {get; set;} 77 public string tagLine {get; set;} 78 public string profilePicture {get; set;} 79 public bool isTopSpeaker {get; set;} 80 public List<Link> links {get; set;} 81 public List<string> sessions {get; set;} 82 public string fullName {get; set;} 83 public List<int> categoryItems {get; set;} 84 public List<QuestionAnswers> questionAnswers {get; set;} 85 } 86 87 public class Category 88 { 89 public int id {get; set;} 90 public string title {get; set;} 91 public List<Item> items {get; set;} 92 public int sort {get; set;} 93 public string type {get; set;} 94 } 95 96 public class Link 97 { 98 public string title {get; set;} 99 public string url {get; set;} 100 public string linType {get; set;} 101 } 102 103 public class Item 104 { 105 public int id {get; set;} 106 public string name {get; set;} 107 public int sort {get; set;} 108 } 109 110 public class Timeslot 111 { 112 public string Code {get; set;} 113 public DateTime? DateAndStart {get; set;} 114 public DateTime? SlotDate {get; set;} 115 public DateTime SlotDuration {get; set;} 116 public string SlotEnd {get; set;} 117 public string SlotStart {get; set;} 118 public string Status {get; set;} 119 120 } 121 122 public class Attribute 123 { 124 public string categoryTitle {get; set;} 125 public int categoryId {get; set;} 126 public int categorySort {get; set;} 127 public int attributeId {get; set;} 128 public string attributeName {get; set;} 129 public int attributeSort {get; set;} 130 } 131 132 public string GetTimeslot(Session session) 133 { 134 string code = session.startsAt != null && session.endsAt != null ? session.startsAt.ToString().GetHashCode().ToString("x") + session.endsAt.ToString().GetHashCode().ToString("x") : "UNDEFINED"; 135 return code; 136 } 137 138 public class QuestionAnswers 139 { 140 public string questionId {get; set;} 141 public string answerValue {get; set;} 142 } 143 144 public class Test 145 { 146 public List<QuestionAnswers> questionAnswers { get; set; } 147 } 148 } 149 150 @{ 151 var parentPages = Dynamicweb.Content.Services.Pages.GetAncestors(Pageview.Page.ID, true); 152 Dynamicweb.Content.Page rootPage = parentPages.Any() ? parentPages.Where(x => x.ItemType == "COMM_EventSection").FirstOrDefault() : new Dynamicweb.Content.Page(); 153 var item = Dynamicweb.Content.Services.Items.GetItem(rootPage.ItemType, rootPage.ItemId); 154 var sessionizeCode = item?["SessionizeCode"].ToString() ?? ""; 155 var eventCode = !string.IsNullOrEmpty(Model.Item?.GetString("SessionizeCode")) ? Model.Item?.GetString("SessionizeCode") : sessionizeCode; 156 var title = Model.Item?.GetString("Title"); 157 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) && Model.Item.GetRawValueString("Theme") != "no-theme" ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 158 string detailTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("DetailTheme")) && Model.Item.GetRawValueString("DetailTheme") != "no-theme" ? " theme " + Model.Item.GetRawValueString("DetailTheme").Replace(" ", "").Trim().ToLower() : ""; 159 detailTheme = detailTheme != "" ? detailTheme : theme; 160 string parentContainerCss = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["session"]) ? "" : "shadow rounded-7"; 161 string sessionQueryParameter = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["session"]) ? 162 Dynamicweb.Context.Current.Request.QueryString["session"] : string.Empty; 163 string sessionDetailCss = !string.IsNullOrEmpty(sessionQueryParameter) ? "p-4 rounded-7" : string.Empty; 164 165 theme = sessionQueryParameter != "" ? detailTheme : theme; 166 167 } 168 169 <div class="h-100 @parentContainerCss @(theme) @sessionDetailCss schedule-container item_@Model.Item.SystemName.ToLower()"> 170 @if (!string.IsNullOrEmpty(eventCode)) 171 { 172 int dayCounter = 1; 173 int dayCounterTab = 1; 174 string sessionizeAll = "https://sessionize.com/api/v2/" + eventCode + "/view/All"; 175 string responseSessionizeAll = GetJson(sessionizeAll).ToString(); 176 //responseSessionizeAll = makeStringReadable(responseSessionizeAll); 177 Root responseResult = Newtonsoft.Json.JsonConvert.DeserializeObject<Root>(responseSessionizeAll); 178 179 var sessionizeSessions = responseResult.sessions; 180 var sessionizeCategories = responseResult.categories; 181 //filter categories 182 sessionizeCategories = sessionizeCategories.Any() ? sessionizeCategories.Where(x => (x.id != 34553) && (x.id != 34539)).ToList() :sessionizeCategories; 183 var sessionizeSpeakers = responseResult.speakers; 184 var sessionizeRooms = responseResult.rooms; 185 var sessionizeDays = sessionizeSessions.Where(x => x.startsAt != null).Select(x => x.startsAt?.Date).Distinct(); 186 187 List<Timeslot> sessionizeTimeslots = new List<Timeslot>(); 188 foreach(var session in sessionizeSessions) 189 { 190 Timeslot slot = new Timeslot(); 191 slot.Code = GetTimeslot(session); 192 slot.DateAndStart = session.startsAt; 193 slot.SlotDate = session.startsAt?.Date; 194 slot.SlotEnd = session.endsAt?.ToString("HH:mm"); 195 slot.SlotStart = session.startsAt?.ToString("HH:mm"); 196 slot.Status = session.isServiceSession ? "SERVICE" : "SESSION"; 197 sessionizeTimeslots.Add(slot); 198 } 199 200 List<Attribute> sessionizeAttributes = new List<Attribute>(); 201 var filteredAttributes = new string []{"Product Category"}; 202 List<string> filteredAttributesId = new List<string>{"35602","186478","186480","186481"}; 203 List<string> filteredAttributesNames = new List<string>{"No","Yes"}; 204 foreach(var category in sessionizeCategories) 205 { 206 foreach(var i in category.items) 207 { 208 if(!filteredAttributesNames.Contains(i.name)) 209 { 210 Attribute attribute = new Attribute(); 211 attribute.categoryTitle = category.title; 212 attribute.categoryId = category.id; 213 attribute.categorySort = category.sort; 214 attribute.attributeId = i.id; 215 attribute.attributeName = i.name; 216 attribute.attributeSort = i.sort; 217 sessionizeAttributes.Add(attribute); 218 } 219 } 220 } 221 222 string sessionDetailLink = Dynamicweb.Context.Current.Request.RawUrl; 223 //var filtersList = new string []{"CONTENT OWNER","PRODUCT","LEVEL","SESSION TYPE","TARGET AUDIENCE","LEARNING PATH"}; 224 var filtersList = new string []{"SESSION TYPE","TARGET AUDIENCE","PRODUCT"}; 225 var sessionTimeslots = sessionizeTimeslots.GroupBy(x => x.Code) 226 .Select(grp => grp.First()).OrderBy(x => x.SlotDate) 227 .ToList(); 228 229 string[] dayNames = {"Pre-day","Day 1","Day 2","Day 3"}; 230 231 232 int tabHeadingCount = 1; 233 int tabContentCount = 1; 234 int accordionCount = 1; 235 236 string categoriesQueryParameter = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["categories"]) ? 237 Dynamicweb.Context.Current.Request.QueryString["categories"] : string.Empty; 238 string dayQueryParameter = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["day"]) ? 239 Dynamicweb.Context.Current.Request.QueryString["day"] : string.Empty; 240 241 242 243 List<Session> sessions = new List<Session>(); 244 for (int i = 0; i < sessionizeSessions.Count; i++) 245 { 246 if (!string.IsNullOrEmpty(categoriesQueryParameter)) 247 { 248 var categories = categoriesQueryParameter?.Split(',')?.Select(Int32.Parse)?.ToList(); 249 var sessionDay = sessionizeSessions[i].startsAt.Value.ToString("dd-MM-yyyy"); 250 251 if (sessionDay == dayQueryParameter) 252 { 253 @* Filter current selected day's sessions based on applied category filters *@ 254 if (sessionizeSessions[i].categoryItems.Any(cat => categories.Contains(cat))) 255 { 256 sessions.Add(sessionizeSessions[i]); 257 } 258 else 259 { 260 sessions.Remove(sessionizeSessions[i]); 261 } 262 } 263 else 264 { 265 @* Keep sessions for other days *@ 266 sessions.Add(sessionizeSessions[i]); 267 } 268 } 269 else 270 { 271 @* Keep all sessions if no category filter is applied *@ 272 sessions.Add(sessionizeSessions[i]); 273 } 274 } 275 276 @* Filter current selected day sessions based on categories *@ 277 if (!string.IsNullOrEmpty(categoriesQueryParameter)) 278 { 279 @* Filter only current selected date sessions *@ 280 if (!string.IsNullOrEmpty(dayQueryParameter)) 281 { 282 // sessionizeSessions = sessionizeSessions.Where(session => session.startsAt.ToString("dd-MM-yyyy") == DateTime.Parse(dayQueryParameter)).ToList(); 283 } 284 var categories = categoriesQueryParameter?.Split(',')?.Select(Int32.Parse)?.ToList(); 285 sessionizeSessions = sessionizeSessions.Where(session => categories.Any(cat => session.categoryItems.Contains(cat))).ToList(); 286 } 287 288 @* Session details page logic *@ 289 if (!string.IsNullOrEmpty(sessionQueryParameter)) 290 { 291 var session = sessionizeSessions.Where(session => session.id == sessionQueryParameter).FirstOrDefault(); 292 var room = sessionizeRooms.Where(room => room.id == session.roomId).FirstOrDefault(); 293 294 var speakers = sessionizeSpeakers.Where(speaker => session.speakers.Contains(speaker.id)).ToList(); 295 var sessionDay = session.startsAt?.ToString("dd-MM-yyyy"); 296 var startTime = session.startsAt?.ToString("HH:mm"); 297 var endTime = session.endsAt?.ToString("HH:mm"); 298 var sessionTitle = session.title; 299 var sessionDescription = session.description != null ? makeStringReadable(session.description) : ""; 300 var roomName = room.name != null ? makeStringReadable(room.name) : ""; 301 var currentPageUrl = Dynamicweb.Context.Current.Request.RawUrl.Split('?')[0]; 302 var clearFiltersUrl = currentPageUrl + "?" + "day=" + sessionDay + "&session=" + session.id; 303 var seeScheduleUrl = currentPageUrl + "?" + "day=" + sessionDay; 304 305 string requestTypeParam = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["RequestType"]) ? 306 "&RequestType=" + Dynamicweb.Context.Current.Request.QueryString["RequestType"] : ""; 307 string layoutTemplate = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["LayoutTemplate"]) ? 308 "&LayoutTemplate=" + Dynamicweb.Context.Current.Request.QueryString["LayoutTemplate"] : ""; 309 310 seeScheduleUrl = seeScheduleUrl + requestTypeParam; 311 seeScheduleUrl = seeScheduleUrl + layoutTemplate; 312 313 bool renderPresentationContainer = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["RequestType"]) && Dynamicweb.Context.Current.Request.QueryString["RequestType"] == "External"; 314 315 string recordingUrl = session.recordingUrl; 316 string liveUrl = session.liveUrl; 317 318 <div class="grid w-100"> 319 <div class="g-col-lg-6 g-col-12 mb-3"> 320 <p class="mb-3 fw-bold">@sessionDay</p> 321 <h1 class="mb-3">@sessionTitle</h1> 322 323 <div class="d-flex align-items-center gap-lg-4 gap-2 flex-wrap"> 324 <span> 325 @RenderIcon("/Files/Templates/Designs/Swift/Assets/icons/clock.svg") 326 @startTime - @endTime 327 </span> 328 <span> 329 @RenderIcon("/Files/Templates/Designs/Swift/Assets/icons/map-pin.svg") 330 @roomName 331 </span> 332 <span> 333 334 <a class="btn btn-secondary" href="@seeScheduleUrl">@RenderIcon("/Files/Templates/Designs/Swift/Assets/icons/calendar.svg") @Translate("Back to event schedule")</a> 335 </span> 336 </div> 337 338 @if (renderPresentationContainer) 339 { 340 string sessionsUrl = "https://sessionize.com/api/v2/"+ eventCode + "/view/Sessions"; 341 string response = GetJson(sessionsUrl).ToString(); 342 343 JArray data = JArray.Parse(response); 344 JObject[] currentSession = data[0]["sessions"].Where(o => (string)o["id"] == session.id).Select(o => (JObject)o).ToArray(); 345 JArray questionsAndAnswers = currentSession[0]["questionAnswers"] != null ? 346 (JArray)currentSession[0]["questionAnswers"] : null; 347 348 <div class="presentation-container mt-3"> 349 @if (questionsAndAnswers != null) 350 { 351 foreach (var element in questionsAndAnswers) 352 { 353 bool renderDownloadLink = element["answer"] != null && !string.IsNullOrEmpty(element["answer"].ToString()); 354 if (renderDownloadLink) 355 { 356 <a class="btn btn-primary" href="@element["answer"]">@Translate("Download presentation")</a> 357 } 358 } 359 } 360 </div> 361 } 362 </div> 363 <div class="g-col-lg-6 g-col-12 mb-3 pt-5"> 364 365 @if(liveUrl != "" && liveUrl != null) 366 { 367 <div><p>@Translate("MeetMicrosoft_Text")</p></div> 368 <div><p><a class="btn btn-primary" href="@liveUrl">@Translate("Booth Schedule")</a></p></div> 369 370 } 371 @if (sessionDescription != null) 372 { 373 <div> 374 <p>@sessionDescription</p> 375 </div> 376 } 377 </div> 378 379 @if (speakers.Any()) 380 { 381 int categoryParameter = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["Category"]) ? 382 Convert.ToInt32(Dynamicweb.Context.Current.Request.QueryString["Category"]) : 0; 383 var groupedAttributes = sessionizeAttributes.GroupBy( 384 attr => attr.categoryTitle, 385 (key, g) => new { Title = key, Items = g.ToList() }); 386 speakers = categoryParameter != 0 ? speakers.Where(speaker => speaker.categoryItems.Contains(categoryParameter)).ToList() : speakers; 387 string headerTitle = Translate("Speakers") + ":"; 388 389 <div class="g-col-12"> 390 <div class="w-100"> 391 <h4 class="mb-4">@headerTitle</h4> 392 </div> 393 394 @* Speakers wall *@ 395 <div class="grid"> 396 @for (int i = 0; i < speakers.Count(); i++) 397 { 398 var columnSize = "grid g-col-12"; 399 400 string viewSpeakerInfoTranslate = Translate("View") + " " + speakers[i].fullName + " " + Translate("info"); 401 string speakerName = speakers[i].fullName != null ? speakers[i].fullName.ToString() : ""; 402 string speakerBio = speakers[i].bio != null ? speakers[i].bio.ToString() : ""; 403 string speakerTagLine = speakers[i].tagLine != null ? speakers[i].tagLine.ToString() : ""; 404 string speakerProfilePicture = speakers[i].profilePicture != null ? speakers[i].profilePicture.ToString() : ""; 405 string speakerCategories = speakers[i].categoryItems != null ? String.Join(",", speakers[i].categoryItems) : ""; 406 var speakerSession = sessions.Where(session => speakers[i].sessions.Contains(session.id)).FirstOrDefault(); 407 var speakerSessions = sessions.Where(session => speakers[i].sessions.Contains(session.id)).ToList(); 408 var sessionsTranslate = speakerSessions.Count() > 1 ? Translate("Sessions") : Translate("Session"); 409 410 <div class="speaker @theme @columnSize gap-0 position-relative rounded-7" data-categories="@speakerCategories"> 411 <div class="h-100 g-col-lg-7 g-col-12 order-last order-md-first max-h-45-em"> 412 <div class="h-100 py-4 max-h-30-em"> 413 <div> 414 <a href="#" class="btn btn-link p-0 text-decoration-none" title="@viewSpeakerInfoTranslate" onclick="event.preventDefault(); new bootstrap.Modal(document.getElementById('SpeakerModal_@i')).show()"> 415 <h4 class="text-start">@makeStringReadable(speakerName)</h4> 416 </a> 417 <p>@speakerTagLine</p> 418 </div> 419 <div class="d-flex flex-column gap-3 justify-content-between max-h-15-em overflow-auto"> 420 <p class="m-0 pb-4">@makeStringReadable(speakerBio)</p> 421 </div> 422 @if (speakers[i].links.Any()) 423 { 424 <div class="d-flex gap-3 align-items-end position-absolute top-100 mt-negative-3-em"> 425 @foreach (var link in speakers[i].links) 426 { 427 string icon = "/Files/Templates/Designs/Swift/Assets/icons/"; 428 429 if (link.url.Contains("twitter")) 430 { 431 icon += "twitter.svg"; 432 } 433 else if (link.url.Contains("linkedin")) 434 { 435 icon += "linkedin.svg"; 436 } 437 else 438 { 439 icon += "link.svg"; 440 } 441 442 <a href="@link.url" title="@link.title" target="_blank"> 443 @RenderIcon(icon) 444 </a> 445 } 446 </div> 447 } 448 </div> 449 </div> 450 <div class="h-100 ratio g-col-lg-5 g-col-12 rounded-7" style="--bs-aspect-ratio: 100%;"> 451 <a class="btn btn-link p-4" title="@viewSpeakerInfoTranslate" onclick="new bootstrap.Modal(document.getElementById('SpeakerModal_@i')).show()"> 452 <img src="@speakerProfilePicture" class="w-100 h-100 rounded-7"></img> 453 </a> 454 </div> 455 <div class="h-100 w-100 position-absolute cursor-pointer d-none"> 456 <a class="btn btn-link stretched-link" title="@viewSpeakerInfoTranslate" onclick="new bootstrap.Modal(document.getElementById('SpeakerModal_@i')).show()"></a> 457 </div> 458 </div> 459 460 <div class="modal fade modal-xl" id="SpeakerModal_@i"> 461 <div class="modal-dialog"> 462 <div class="modal-content @theme rounded-7"> 463 <div class="modal-body p-0" id="SpeakerModalBodyContainer_@i"> 464 <div class="close-container position-absolute p-3 end-0 m-3 bg-white rounded-7 z-index-9"> 465 <button type="button" class="btn-close bg-dark z-index-9" data-bs-dismiss="modal" aria-label="Close"></button> 466 </div> 467 <div class="grid @theme gap-0 rounded-7"> 468 <div class="h-100 g-col-lg-7 g-col-12 order-last order-md-first"> 469 <div class="h-100 p-4 overflow-auto max-h-30-em"> 470 <div> 471 <h4>@makeStringReadable(speakerName)</h4> 472 <p>@speakerTagLine</p> 473 </div> 474 <div class="d-flex flex-column gap-3 justify-content-between"> 475 <p class="m-0">@makeStringReadable(speakerBio)</p> 476 </div> 477 <div class="mt-4 d-grid"> 478 <p class="m-0 fw-bold">@sessionsTranslate</p> 479 @foreach (var _item in speakerSessions) 480 { 481 var sessionLink = currentPageUrl.IndexOf("?") > 0 ? currentPageUrl + "&session=" + _item.id : currentPageUrl + "?session=" + _item.id; 482 <a class="btn btn-link text-start p-0 mb-2" title="@_item.title" href="@sessionLink"> 483 @_item.title 484 </a> 485 } 486 </div> 487 @if (speakers[i].links.Any()) 488 { 489 <div class="d-flex gap-3 align-items-end"> 490 @foreach (var link in speakers[i].links) 491 { 492 string icon = "/Files/Templates/Designs/Swift/Assets/icons/"; 493 494 if (link.url.Contains("twitter")) 495 { 496 icon += "twitter.svg"; 497 } 498 else if (link.url.Contains("linkedin")) 499 { 500 icon += "linkedin.svg"; 501 } 502 else 503 { 504 icon += "link.svg"; 505 } 506 507 <a href="@link.url" title="@link.title" target="_blank"> 508 @RenderIcon(icon) 509 </a> 510 } 511 </div> 512 } 513 </div> 514 </div> 515 <div class="h-100 ratio g-col-lg-5 g-col-12" style="--bs-aspect-ratio: 100%"> 516 <img src="@speakerProfilePicture" class="rounded-7"></img> 517 </div> 518 </div> 519 </div> 520 </div> 521 </div> 522 </div> 523 524 } 525 </div> 526 </div> 527 } 528 </div> 529 } 530 else 531 { 532 <nav class="tabs rounded-7"> 533 <ul class="nav nav-tabs days-tabs bg-light-grey rounded-7-top" role="tablist"> 534 @foreach (var day in sessionizeDays) 535 { 536 string dayDate = day?.ToString("dd-MM-yyyy"); 537 string dayName = dayNames[tabHeadingCount - 1]; 538 bool showCounterWithTabName = dayName == "Training" ? true : false; 539 string tabAnchorRaw = showCounterWithTabName ? dayName + tabHeadingCount : dayName; 540 string tabAnchor = "tabname" + tabAnchorRaw + tabHeadingCount; 541 bool hasDayParam = !string.IsNullOrEmpty(dayQueryParameter); 542 string activeClass = hasDayParam && DateTime.Parse(dayQueryParameter) == DateTime.Parse(dayDate) ? 543 "active" : tabHeadingCount == 1 && !hasDayParam ? "active" : ""; 544 545 string firstTabCss = tabHeadingCount == 1 ? "rounded-7-top-left" : ""; 546 547 <li class="flex-mobile-auto @(firstTabCss)" role="presentation"> 548 <a class="session-tab nav-link d-grid text-decoration-none p-3 pe-4 @(activeClass) @(firstTabCss)" href="@("#" + tabAnchor)" aria-controls="@tabAnchor" role="tab" data-toggle="tab" data-date="@dayDate"> 549 <span class="fw-bold">@dayName</span> <span>@dayDate</span> 550 </a> 551 </li> 552 tabHeadingCount += 1; 553 } 554 </ul> 555 </nav> 556 557 <div class="tab-content days-tabs-container p-lg-4 p-2 rounded-7-bottom"> 558 @foreach (var day in sessionizeDays) 559 { 560 string dayClass = tabContentCount == 1 ? "active" : ""; 561 string timeslotsDay = day?.ToString("dd-MM-yyyy"); 562 string dayName = dayNames[tabContentCount - 1]; 563 bool showCounterWithTabName = dayName == "Training" ? true : false; 564 string tabAnchorRaw = showCounterWithTabName ? dayName + tabContentCount : dayName; 565 string tabAnchor = "tabname" + tabAnchorRaw + tabContentCount; 566 string dayAnchor = showCounterWithTabName ? dayName + tabContentCount : dayName; 567 string dayID = "day" + tabContentCount; 568 569 var daySessionsList = sessionizeSessions.Where(x => x.startsAt?.Date == day); 570 var dayAttributes = new List<int>(); 571 foreach(var daySession in daySessionsList) 572 { 573 dayAttributes.AddRange(daySession.categoryItems); 574 } 575 576 var dayAttributesFiltered = sessionizeAttributes.Where(item => dayAttributes.Any(filter => filter.Equals(item.attributeId))); 577 //remove attribute categories based on filtersList 578 dayAttributesFiltered = dayAttributesFiltered.Where(item => filtersList.Contains(item.categoryTitle.ToUpper())).ToList(); 579 var dayAttributesCategories = dayAttributesFiltered.Select(item => item.categoryTitle).Distinct(); 580 581 bool hasDayParam = !string.IsNullOrEmpty(dayQueryParameter); 582 bool matchingDate = hasDayParam && (DateTime.Parse(dayQueryParameter) == DateTime.Parse(timeslotsDay)); 583 var activeTabClass = matchingDate ? 584 "active" : tabContentCount == 1 && !hasDayParam ? "active" : ""; 585 586 var activeTabContainerClass = matchingDate ? 587 "show" : tabContentCount == 1 && !hasDayParam ? "show" : ""; 588 589 <div id="@tabAnchor" role="tabpanel" class="tab-pane @activeTabClass"> 590 591 @*<!--Filters--> 592 @if (dayAttributesFiltered.Any()) 593 { 594 <div class="grid"> 595 <div class="g-col-lg-4 g-col-12"> 596 <label class="fw-bold" for="filter-sessions-1">@Translate("Filter Sessions")</label> 597 <select id="filter-sessions-@tabContentCount" name="filter-sessions" class="form-control select2-multiple filter-session-ref filter-session-trigger" multiple="multiple" data-date="@timeslotsDay"> 598 @foreach (var category in dayAttributesFiltered) 599 { 600 //Take into consideration the dayParam 601 var categories = !string.IsNullOrEmpty(categoriesQueryParameter) ? categoriesQueryParameter?.Split(',')?.Select(Int32.Parse)?.ToList() : null; 602 var selected = !string.IsNullOrEmpty(categoriesQueryParameter) && categories.Contains(category.attributeId) ? "selected" : ""; 603 <option @selected value='@category.attributeId'>@category.attributeName @category.categoryTitle</option> 604 } 605 </select> 606 @if (!string.IsNullOrEmpty(categoriesQueryParameter)) 607 { 608 var clearFiltersUrl = Dynamicweb.Context.Current.Request.RawUrl.Split('?')[0] + "?" + "day=" + timeslotsDay; 609 //include RequestType & LayoutTemplate params if present (embedded page scenario) 610 string requestTypeParam = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["RequestType"]) ? 611 "&RequestType=" + Dynamicweb.Context.Current.Request.QueryString["RequestType"] : ""; 612 string layoutTemplate = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["LayoutTemplate"]) ? 613 "&LayoutTemplate=" + Dynamicweb.Context.Current.Request.QueryString["LayoutTemplate"] : ""; 614 615 clearFiltersUrl = clearFiltersUrl + requestTypeParam; 616 clearFiltersUrl = clearFiltersUrl + layoutTemplate; 617 <a class="btn btn-link" href="@clearFiltersUrl" title="Clear filters"> 618 @Translate("Clear filters") 619 </a> 620 } 621 </div> 622 </div> 623 } 624 625 <div class="hidden"> 626 <div class="filterData"> 627 @foreach (var filter in filtersList) 628 { 629 string filterName = filter; 630 } 631 </div> 632 </div> 633 634 <!--FiltersEnd-->*@ 635 636 <!--Filters--> 637 @if (dayAttributesFiltered.Any()) 638 { 639 <div class="grid"> 640 @foreach(var filterCategory in dayAttributesCategories) 641 { 642 string filterCategoryName = filterCategory; 643 string filterLabel = Translate("Filter " + filterCategoryName); 644 filterCategoryName = filterCategoryName.Replace(" ","-").ToLower(); 645 var dayAttributesList = dayAttributesFiltered.OrderBy(item=>item.attributeName).Where(item=>item.categoryTitle == filterCategory).ToList(); 646 647 <div class="g-col-lg-4 g-col-12"> 648 <label class="fw-bold" for="filter-@filterCategoryName-@tabContentCount">@filterLabel</label> 649 <select id="filter-@filterCategoryName-@tabContentCount" name="filter-@filterCategoryName" class="filter-dropdown form-control select2-multiple filter-@filterCategoryName-ref filter-@filterCategoryName-trigger" multiple="multiple" data-date="@timeslotsDay"> 650 @foreach (var category in dayAttributesList) 651 { 652 @* Take into consideration the dayParam *@ 653 var categories = !string.IsNullOrEmpty(categoriesQueryParameter) ? categoriesQueryParameter?.Split(',')?.Select(Int32.Parse)?.ToList() : null; 654 var selected = !string.IsNullOrEmpty(categoriesQueryParameter) && categories.Contains(category.attributeId) ? "selected" : ""; 655 <option @selected value='@category.attributeId'>@category.attributeName @category.categoryTitle</option> 656 } 657 </select> 658 @if (!string.IsNullOrEmpty(categoriesQueryParameter)) 659 { 660 var clearFiltersUrl = Dynamicweb.Context.Current.Request.RawUrl.Split('?')[0] + "?" + "day=" + timeslotsDay; 661 @* include RequestType & LayoutTemplate params if present (embedded page scenario) *@ 662 string requestTypeParam = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["RequestType"]) ? 663 "&RequestType=" + Dynamicweb.Context.Current.Request.QueryString["RequestType"] : ""; 664 string layoutTemplate = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.QueryString["LayoutTemplate"]) ? 665 "&LayoutTemplate=" + Dynamicweb.Context.Current.Request.QueryString["LayoutTemplate"] : ""; 666 667 clearFiltersUrl = clearFiltersUrl + requestTypeParam; 668 clearFiltersUrl = clearFiltersUrl + layoutTemplate; 669 <a class="btn btn-link clear-filters" href="@clearFiltersUrl" title="Clear filters" data-target-dropdown="filter-@filterCategoryName-@tabContentCount"> 670 @Translate("Clear filters") 671 </a> 672 } 673 </div> 674 675 } 676 </div> 677 } 678 679 <div class="hidden"> 680 <div class="filterData"> 681 @foreach (var filter in filtersList) 682 { 683 string filterName = filter; 684 } 685 </div> 686 </div> 687 688 <!--FiltersEnd--> 689 690 691 <!-- Second level content start --> 692 <div class="tab-content2 tab-content-schedule"> 693 <!-- All sessions start --> 694 <div id='@(dayID + "_allsessions")' class="tab-pane fade in @activeTabContainerClass"> 695 <div class="panel-group mt-4" id="@(dayID + "_allsessions_timeline")"> 696 <p class="not-found mb-0 d-none">@Translate("No items found.")</p> 697 @foreach (var timeslot in sessionTimeslots.Where(x => x.SlotDate == day).OrderBy(x => x.SlotStart)) 698 { 699 string timeslotCode = timeslot.Code; 700 var start = timeslot.SlotStart; 701 var end = timeslot.SlotEnd; 702 var currentSessions = sessions.Where(x => GetTimeslot(x) == timeslotCode); // filtered sessions list by day & categories [based on sessionizeSessions] 703 704 if (currentSessions.Any()) 705 { 706 string breakSessionTheme = currentSessions.Any(session => session.isServiceSession) ? "theme ice-blue" : ""; 707 string isBreakSession = currentSessions.Any(session => session.isServiceSession) ? "is-break" : ""; 708 <!-- Lecture start --> 709 <div class="grid gap-lg-4 panel schedule-item border p-4 pt-6 mb-3 position-relative rounded-7 grid-auto-rows-1-fr @timeslotCode @isBreakSession" data-duration="" data-status=""> 710 <div class="g-col-12 time-wrapper position-absolute py-3 px-4 ms-4 rounded-7-bottom"> 711 <strong class="time">@start - @end</strong> 712 </div> 713 @foreach (var session in currentSessions) 714 { 715 716 var sessionRoom = sessionizeRooms.Where(x => x.id == session.roomId).FirstOrDefault(); 717 string sessionRoomName = sessionRoom != null ? makeStringReadable(sessionRoom.name) : "N/A"; 718 var isBreak = session.isServiceSession ? "full" : ""; 719 var test = session.isServiceSession ? "tested" : ""; // Check data structure here 720 var publishingStatus = "FULL"; 721 var approvalStatus = "approved"; 722 var categoriesList = session.categoryItems; 723 var _categories = String.Join(",", categoriesList.ToArray()); 724 string categories = ""; 725 726 var attributes = sessionizeAttributes.Where(item => categoriesList.Any(category => category == item.attributeId)); 727 string sessionDetailLinkAdjusted = sessionDetailLink.IndexOf("?") > 0 ? sessionDetailLink + "&session=" + session.id : sessionDetailLink + "?session=" + session.id; 728 string sessionTitle = makeStringReadable(!string.IsNullOrEmpty(session.title) ? session.title : "TBD"); 729 string columnCss = currentSessions.Count() == 1 ? "g-col-12" : "g-col-lg-6 g-col-12"; 730 <div class="d-grid gap-3 @columnCss title border-bottom my-3 pb-3 @test"> 731 <div class="session-name" data-publishing="@publishingStatus" data-categories="@_categories" data-approval="@approvalStatus" data-code="@session.id"> 732 @if (publishingStatus == "FULL" && isBreak == "") 733 { 734 <a class="text-decoration-none fw-bold" href='@sessionDetailLinkAdjusted' data-id="@session.id"><h5 class="session-header">@sessionTitle</h5></a> 735 } 736 else 737 { 738 <h5 class="session-header fw-bold">@sessionTitle</h5> 739 } 740 </div> 741 742 <div class="mb-2"> 743 @RenderIcon("/Files/Templates/Designs/Swift/Assets/icons/map-pin.svg") 744 <span class="speaker-name">@sessionRoomName</span> 745 </div> 746 747 @if (attributes.Any()) 748 { 749 <div> 750 <p class="fw-bold mb-2 tags-text">@Translate("Tags")</p> 751 <div class="d-flex flex-wrap gap-2"> 752 @foreach (var attr in attributes) 753 { 754 <a class="session-tags text-decoration-underline fs-7" href="#" data-target="filter-sessions-@tabContentCount" id="@attr.attributeId">@attr.attributeName</a> 755 } 756 </div> 757 </div> 758 } 759 760 </div> 761 } 762 </div> 763 <!--Lecture end--> 764 } 765 } 766 </div> 767 </div> 768 </div> 769 </div> 770 771 tabContentCount += 1; 772 } 773 </div> 774 } 775 } 776 777 </div> 778 779 780 @helper RenderIcon(string icon) 781 { 782 if (System.IO.Path.GetExtension(icon).ToLower() == ".svg") 783 { 784 if (!icon.ToLower().Contains("none") && icon != string.Empty) 785 { 786 <span class="icon-auto"> 787 @ReadFile(icon) 788 </span> 789 } 790 } 791 } 792 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/slim-select/2.6.0/slimselect.css" integrity="sha512-ijXMfMV6D0xH0UfHpPnqrwbw9cjd4AbjtWbdfVd204tXEtJtvL3TTNztvqqr9AbLcCiuNTvqHL5c9v2hOjdjpA==" crossorigin="anonymous" referrerpolicy="no-referrer" /> 793 <script src="https://cdnjs.cloudflare.com/ajax/libs/slim-select/2.6.0/slimselect.min.js" integrity="sha512-0E8oaoA2v32h26IycsmRDShtQ8kMgD91zWVBxdIvUCjU3xBw81PV61QBsBqNQpWkp/zYJZip8Ag3ifmzz1wCKQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>