From 6e78d5d0bf88d25db48a82e498fe0193dc9baedf Mon Sep 17 00:00:00 2001
From: zaultavangar <zaul_tavangar@brown.edu>
Date: Sun, 17 Dec 2023 20:13:21 -0500
Subject: developing CalendarBox and CollectionCalendarView

---
 src/client/views/nodes/calendarBox/CalendarBox.tsx | 110 ++++++++++++++++++++-
 1 file changed, 109 insertions(+), 1 deletion(-)

(limited to 'src/client/views/nodes/calendarBox/CalendarBox.tsx')

diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx
index 0aa3b4ccc..989feb774 100644
--- a/src/client/views/nodes/calendarBox/CalendarBox.tsx
+++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx
@@ -5,6 +5,13 @@ import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps, ViewBoxBaseCompon
 import { FieldView, FieldViewProps } from '../FieldView';
 import { StrCast } from '../../../../fields/Types';
 import { makeObservable } from 'mobx';
+import { dateRangeStrToDates } from '../../../../Utils';
+import { Calendar, EventClickArg, EventSourceInput } from '@fullcalendar/core'
+import dayGridPlugin from '@fullcalendar/daygrid'
+import multiMonthPlugin from '@fullcalendar/multimonth'
+import { faListNumeric } from '@fortawesome/free-solid-svg-icons';
+
+type CalendarView = 'month' | 'multi-month' | 'week';
 
 @observer
 export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>(){
@@ -12,6 +19,103 @@ export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>(){
         return FieldView.LayoutString(CalendarBox, fieldKey);
     }
 
+    componentDidMount(): void {
+        
+    }
+
+    componentWillUnmount(): void {
+        
+    }
+
+    _calendarRef = React.createRef<HTMLElement>()
+
+    get dateRangeStr (){
+        return StrCast(this.Document.date_range);
+    }
+
+    // Choose a calendar view based on the date range 
+    get calendarViewType (): CalendarView {
+        const [fromDate, toDate] = dateRangeStrToDates(this.dateRangeStr);
+
+        if (fromDate.getFullYear() !== toDate.getFullYear() || fromDate.getMonth() !== toDate.getMonth()) return 'multi-month';
+
+        if (Math.abs(fromDate.getDay() - toDate.getDay()) > 7) return 'month';
+        return 'week';
+    }
+
+    get calendarStartDate () {
+        return this.dateRangeStr.split("|")[0];
+    }
+
+    get calendarToDate () {
+        return this.dateRangeStr.split("|")[1];
+    }
+
+    get childDocs (): Doc[] {
+        return this.childDocs; // get all sub docs for a calendar
+    }
+
+    docBackgroundColor (type: string): string {
+        // TODO: Return a different color based on the event type
+        return 'blue';
+    }
+
+    get calendarEvents (): EventSourceInput | undefined {
+        if (this.childDocs.length === 0) return undefined;
+        return this.childDocs.map((doc, idx) => {
+            const docTitle = StrCast(doc.title);
+            const docDateRange = StrCast(doc.date_range);
+            const [startDate, endDate] = dateRangeStrToDates(docDateRange);
+            const docType = doc.type;
+            const docDescription = doc.description ? StrCast(doc.description): "";
+
+            return {
+                title: docTitle,
+                start: startDate,
+                end: endDate,
+                allDay: false,
+                classNames:[StrCast(docType)], // will determine the style 
+                editable: false, // subject to change in the future
+                backgroundColor: this.docBackgroundColor(StrCast(doc.type)),
+                color: 'white',
+                extendedProps: {
+                    description: docDescription
+                },
+                
+            }
+
+        })
+    }
+
+    handleEventClick = (arg: EventClickArg) => {
+        // TODO: open popover with event description, option to open CalendarManager and change event date, delete event, etc.
+    }
+
+    calendarEl: HTMLElement = document.getElementById('calendar-box-v1')!;
+
+    // https://fullcalendar.io
+    get calendar() {
+        return new Calendar(this.calendarEl, 
+            {
+                plugins: [this.calendarViewType === 'multi-month' ? multiMonthPlugin : dayGridPlugin],
+                headerToolbar: {
+                    left: 'prev,next today',
+                    center: 'title',
+                    right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
+                },
+                initialDate: this.calendarStartDate,
+                navLinks: true,
+                editable: false,
+                displayEventTime: false,
+                displayEventEnd: false,
+                events: this.calendarEvents,
+                eventClick: this.handleEventClick
+            }
+        )
+        
+    }
+
+
     constructor(props: any){
         super(props);
         makeObservable(this);
@@ -19,7 +123,11 @@ export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>(){
 
     render(){
         return (
-            <div></div>  
+            <div className='calendar-box-conatiner'>
+                <div id='calendar-box-v1'>
+
+                </div>
+            </div>  
         );
         
     }
-- 
cgit v1.2.3-70-g09d2

