From 3391962b0ffe015cb2fa607b251f8aa413417a5c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Torben=20B=C3=B6hnke?=
 <torben.boehnke-makerspace@ruhr-uni-bochum.de>
Date: Thu, 14 Sep 2023 16:35:02 +0200
Subject: [PATCH] Kalender Update

- Fix: Serienelemente wurden nur selten angezeigt
- scroll to top/bottom buttons added
- toolbar Aufbau nach width angepasst
- overflow aus verschiedenen boxen (daygrid events, buttons form) gefixed
---
 docs/calendar.html               |  2 +-
 docs/index.md                    |  2 +-
 docs/javascripts/ics_calendar.js | 91 ++++++++++++++++++++++----------
 docs/stylesheets/calendar.css    | 12 +++++
 docs/stylesheets/extra.css       |  5 ++
 docs/stylesheets/variables.css   |  2 +-
 6 files changed, 82 insertions(+), 32 deletions(-)

diff --git a/docs/calendar.html b/docs/calendar.html
index 18b05489a..f71c94915 100644
--- a/docs/calendar.html
+++ b/docs/calendar.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="de">
 <head>
   <title>Calendar</title>
   <script src="javascripts/ical.js"></script> <!-- calls ical.js library to parse the ics-data from the calendar file into data the fullcalendar-library can work with -->
diff --git a/docs/index.md b/docs/index.md
index 9ae2478f8..26a34f1c8 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -156,7 +156,7 @@ glightbox: false
       <div class="custom-heading">Dienstleistungen</div>
       <div class="custom-inner-image" style="background-image: url('medien/Button_Dienstleistungen.jpg');"></div>
       <div class="custom-description">Wir unterstützen Dich dabei, Dein Vorhaben umzusetzen. Sprich uns für ein Angebot für die individuelle Zusammenarbeit bitte gern an!</div>
-      <div class="custom-copyright">©RUB, Marquard</div>
+      <div class="custom-copyright">©RUB-Makerspace: Dienstleistungen (CC BY-SA 4.0)</div>
       <div class="custom-overlay"></div>
     </a>
   </div>  
diff --git a/docs/javascripts/ics_calendar.js b/docs/javascripts/ics_calendar.js
index 8089000a5..54c216bd0 100644
--- a/docs/javascripts/ics_calendar.js
+++ b/docs/javascripts/ics_calendar.js
@@ -30,23 +30,43 @@ fetchAndParseICS()
   for (let vevent of vevents) {
     let summary = vevent.getFirstPropertyValue('summary');
     let description = vevent.getFirstPropertyValue('description');
+    
+    if (summary.toLowerCase().includes('nutzung')) {  // Skip events with "Nutzung" in the title
+      continue;
+    }
+    
     let dtstartIcal = vevent.getFirstPropertyValue('dtstart');
     let dtendIcal = vevent.getFirstPropertyValue('dtend');
 
-    let dtstart = dtstartIcal ? dtstartIcal.toJSDate() : null;
-    let dtend = dtendIcal ? dtendIcal.toJSDate() : null;
+    let duration = dtendIcal.subtractDate(dtstartIcal);
 
-    if (summary.toLowerCase().includes('nutzung')) {  // Skip events with "Nutzung" in the title
-      continue;
+    let rrule = vevent.getFirstPropertyValue('rrule');
+    if (rrule) {
+      // Handle recurring events
+      let iterator = rrule.iterator(dtstartIcal);
+      let next;
+      while ((next = iterator.next())) {
+        let dtend = next.clone();
+        dtend.addDuration(duration); // Apply duration to get end time for the occurrence
+        
+        calendarEvents.push({
+          title: summary,
+          start: next.toJSDate(),
+          end: dtend.toJSDate(),
+          description: description,
+          allDay: next.isDate
+        });
+      }
+    } else {
+      // Handle non-recurring events
+      calendarEvents.push({
+        title: summary,
+        start: dtstartIcal ? dtstartIcal.toJSDate() : null,
+        end: dtendIcal ? dtendIcal.toJSDate() : null,
+        description: description,
+        allDay: dtstartIcal ? dtstartIcal.isDate : false
+      });
     }
-
-    calendarEvents.push({
-      title: summary,
-      start: dtstart,
-      end: dtend,
-      description: description,
-      allDay: dtstartIcal ? dtstartIcal.isDate : false
-    });
   }
 
 // defines toolbar based on width
@@ -59,9 +79,9 @@ function getToolbarConfig() {
   if (width <= mobileWidth) {
     return {
       toolbar: {
-        start: 'prev',
-        center: 'title',
-        end: 'next'
+        start: '',
+        center: 'prev title next',
+        end: 'jumpToBottom'
       },
       view: 'listYear'
     };
@@ -70,7 +90,7 @@ function getToolbarConfig() {
       toolbar: {
         start: 'prev,next,today',
         center: 'title',
-        end: 'dayGridMonth,listYear'
+        end: 'dayGridMonth,listYear jumpToBottom'
       }
     };
   }
@@ -94,17 +114,40 @@ function initializeCalendar() {
             click: function() {
                 showPastEvents = !showPastEvents;
                 handlePastEventsVisibility(); 
+            }
+        },
+        jumpToTop: {
+          text: 'â–²',
+          hint: 'Zum Kalender-Anfang',
+            click: function() {
+              var ef = document.getElementById('event-form');
+              if(ef) {
+                document.getElementById('fc-dom-1').scrollIntoView({ behavior: 'smooth', block: 'center' });
+              } else {
+                document.getElementById('form-container').scrollIntoView({ behavior: 'smooth', block: 'end' });
               }
-          }
+            }
+        },
+        jumpToBottom: {
+          text: 'â–¼',
+          hint: 'Zum Kalender-Ende',
+            click: function() {
+                document.getElementById('calendar').scrollIntoView({ behavior: 'smooth', block: 'end' });
+            }
+        },
       },
       headerToolbar: config.toolbar,
       footerToolbar: {
-        start: 'togglePastEvents'
+        start: 'togglePastEvents',
+        end: 'jumpToTop'
       },
       views: {
         dayGridMonth: { buttonText: 'Kalender'},
         listYear: { buttonText: 'Liste' },
       },
+      buttonText: {
+        today: 'Heute'
+      },
       contentHeight: "auto",
       events: calendarEvents,
       eventDisplay: 'block',
@@ -171,7 +214,7 @@ function initializeCalendar() {
             <label for="event-info" style="font-size: 18px"><strong>Deine Teilnahmeanfrage für:</strong></label>
             <p name="event-info" id="event-info" readonly>${info.event.title + '\nam ' + formattedDate + ' von ' + formattedStartTime + ' bis ' + formattedEndTime + ' Uhr'}</textarea>
         </div>   
-        <input type="hidden" name="recipients"    value="Torben.Boehnke-makerspace@ruhr-uni-bochum.de"/>
+        <input type="hidden" name="recipients"    value="makerspace@ruhr-uni-bochum.de"/>
             <input type="hidden" name="mail_options" value="charset=UTF-8,Exclude=realname;honigtopf;schicken;FromAddr"/>
             <input type="hidden" name="good_url"      value="https://makerspace.io.noc.ruhr-uni-bochum.de/homepage/danke/"  />       
             <input type="hidden" name="good_template" value="https://makerspace.io.noc.ruhr-uni-bochum.de/homepage/danke/"  />
@@ -293,8 +336,6 @@ function adjustHeight() {
 
   newHeight = wrapperHeight + 10;
 
-  console.log("newHeight:", newHeight)
-
   // Directly set the height of the iframe in the parent
   var iframeInParent = window.parent.document.getElementById('calendar');
   if (iframeInParent) {
@@ -324,14 +365,6 @@ function handlePastEventsVisibility() {
       });
   }
   var visibleEvents = calendar.getEvents();
-  console.log("All visible events:", visibleEvents);
-  var multiDayEvents = visibleEvents.filter(function(event) {
-    var start = event.start;
-    var end = event.end || start;
-    return (end.getTime() - start.getTime()) > 86400000;
-});
-console.log("Filtered multi-day events:", multiDayEvents);
-
 }
 });
 
diff --git a/docs/stylesheets/calendar.css b/docs/stylesheets/calendar.css
index b21597532..333ed75c9 100644
--- a/docs/stylesheets/calendar.css
+++ b/docs/stylesheets/calendar.css
@@ -53,6 +53,8 @@ body {
 .fc {
     color: var(--high-contrast-font);
     padding: 1px;
+    hyphens: auto;
+    text-wrap: balance;
 }
 
 .fc-event-main {
@@ -100,6 +102,15 @@ body {
     cursor: pointer;
 }
 
+.fc .fc-toolbar-title {
+    display: inline-block;
+    vertical-align: middle;
+}
+
+.fc-direction-ltr .fc-toolbar > * > :not(:first-child) {
+    margin-left: 0.75rem;
+}
+
 /* The classes defining the design of the contact form */
 #form-container {
     display: block;
@@ -147,6 +158,7 @@ body {
 }
 
 
+
 /* Design of the text-field of the contact form that holds the selected event informations. */
 .event-subject p {
     width: 100%;
diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css
index 3fa54ba9b..2cf3819a6 100644
--- a/docs/stylesheets/extra.css
+++ b/docs/stylesheets/extra.css
@@ -64,6 +64,9 @@ html .md-footer-meta.md-typeset a:hover  {
 
 .md-typeset a {
     text-decoration:underline;
+    hyphens: auto;
+    -webkit-hyphens: auto;
+    -moz-hyphens: auto;
 }
 
 .md-typeset a:focus, .md-typeset a:hover {
@@ -761,7 +764,9 @@ a.slide-button:hover {
   background-color: rgba(15, 54, 90, 1);
   color: white;
   hyphens: auto;
+  -moz-hyphens: auto;
   text-wrap: balance;
+  white-space: pre-wrap;
 }
 
 .md-typeset .md-button:is(:focus) {
diff --git a/docs/stylesheets/variables.css b/docs/stylesheets/variables.css
index 66d7cff37..3f3f4b0b8 100644
--- a/docs/stylesheets/variables.css
+++ b/docs/stylesheets/variables.css
@@ -1,7 +1,7 @@
 :root {
     --md-primary-fg-color: #003561;
     --md-accent-fg-color: #651e38;
-    --md-default-bg-color: #FDFFE0;
+    --md-default-bg-color: #fdffe000;
     --md-text-font: "RUBFlama"; 
     --md-footer-bg-color--dark: white;
     --border-radius: 4px;
-- 
GitLab